poj3259Wormholes (Bellman_Ford/SPFA/Floyed算法判断是否存在负环)

时间:2023-02-23 23:36:08

题目链接http://poj.org/problem?id=3259

题目大意:一个图,有n个顶点,其中有m条边是双向的且权值为为正,w条边是单向的且权值为负,判断途中是否存在负环,如果有输出YES,没有输出NO。

Sample Input

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

Sample Output

NO
YES 解题思路:套用Bellman_Ford算法判断图是否存在负环
具体详见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,w,dist[],tot;
struct node{
int from,to,d;
}edge[];
bool Bellman_Ford()
{
for(int i=;i<=n;i++) dist[i]=inf; //初始化
dist[]=;
for(int i=;i<n;i++)
{
bool flag=; //判断该轮是否可以松弛
for(int j=;j<tot;j++)
{
if(dist[edge[j].to]>dist[edge[j].from]+edge[j].d)
{ //进行松弛操作
dist[edge[j].to]=dist[edge[j].from]+edge[j].d;
flag=;
}
}
if(flag) return false; //当轮没有松弛表示没有负环
}
for(int i=;i<tot;i++)
{
if(dist[edge[i].to]>dist[edge[i].from]+edge[i].d) //仍然可以松弛,表示有负环
return true;
}
return false;
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&w);
tot=;
for(int i=;i<=m;i++) //双向边
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
edge[tot].from=a;
edge[tot].to=b;
edge[tot].d=c;
tot++;
edge[tot].from=b;
edge[tot].to=a;
edge[tot].d=c;
tot++;
}
for(int i=;i<=w;i++) //单向负边
{
scanf("%d%d%d",&edge[tot].from,&edge[tot].to,&edge[tot].d);
edge[tot].d=-edge[tot].d;
tot++;
}
if(Bellman_Ford())
printf("YES\n");
else
printf("NO\n");
}
return ;
}

套用SPFA算法判断图是否存在负环

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<cmath>
#include<list>
#include<deque>
#include<cstdlib>
#include<bitset>
#include<stack>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int maxn=;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
const int dir[][]={{,},{-,},{,},{,-}};
ll n,m,p;
int head[maxn],vis[maxn],InQueue[maxn],dis[maxn];
int tot;
struct Edge{
int to,w,next;
}edge[maxn*];
void Add_Edge(int u,int v,int w)
{
edge[tot].to=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
}
bool spfa()
{
queue<int> que;
while(que.size())que.pop();
que.push();
vis[]=;
InQueue[]++;
dis[]=;
while(que.size())
{
int u=que.front();
que.pop();
vis[u]=;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].w)
{
dis[v]=dis[u]+edge[i].w;
if(!vis[v])
{
vis[v]=;
InQueue[v]++;
if(InQueue[v]>=n)return true;
que.push(v);
}
}
}
}
return false;
}
int main()
{
int t;
cin>>t;
while(t--)
{
tot=;
cin>>n>>m>>p;
for(int i=;i<=n;i++)
{
vis[i]=InQueue[i]=;
dis[i]=INF;
head[i]=-;
}
int u,v,w;
for(int i=;i<m;i++)
{
cin>>u>>v>>w;
Add_Edge(u,v,w);
Add_Edge(v,u,w);
}
for(int i=;i<p;i++)
{
cin>>u>>v>>w;
w=-w;
Add_Edge(u,v,w);
}
if(spfa()) puts("YES");
else puts("NO");
}
return ;
}

Floyed算法判断负环:

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<cmath>
#include<list>
#include<deque>
#include<cstdlib>
#include<bitset>
#include<stack>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int maxn=;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
const int dir[][]={{,},{-,},{,},{,-}};
int n,m,p,mp[][];
bool Floyed()
{
for(int k=;k<=n;k++)
{
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
{
if(mp[i][j]>mp[i][k]+mp[k][j])
mp[i][j]=mp[i][k]+mp[k][j];
}
if(mp[i][i]<)return true;
}
}
return false;
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>m>>p;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
if(i==j)mp[i][j]=;
else mp[i][j]=INF;
}
int u,v,w;
for(int i=;i<m;i++)
{
cin>>u>>v>>w;
if(w<mp[u][v]) mp[u][v]=mp[v][u]=w;
}
for(int i=;i<p;i++)
{
cin>>u>>v>>w;
mp[u][v]=-w;
}
if(Floyed())puts("YES");
else puts("NO");
}
return ;
}

poj3259Wormholes (Bellman_Ford/SPFA/Floyed算法判断是否存在负环)的更多相关文章

  1. POJ 3259 Wormholes(bellman&lowbar;ford,判断有没有负环回路)

    题意:John的农场里field块地,path条路连接两块地,hole个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts.我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前 ...

  2. vijos1053 用spfa判断是否存在负环

    MARK 用spfa判断是否存在负环 判断是否存在负环的方法有很多, 其中用spfa判断的方法是:如果存在一个点入栈两次,那么就存在负环. 细节想想确实是这样,按理来说是不存在入栈两次的如果边权值为正 ...

  3. POJ 3259 Wormholes(最短路,判断有没有负环回路)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24249   Accepted: 8652 Descri ...

  4. &lbrack;ACM&rsqb; 最短路算法整理(bellman&lowbar;ford &comma; SPFA &comma; floyed &comma; dijkstra 思想,步骤及模板)

    以杭电2544题目为例 最短路 Problem Description 在每年的校赛里,全部进入决赛的同学都会获得一件非常美丽的t-shirt. 可是每当我们的工作人员把上百件的衣服从商店运回到赛场的 ...

  5. bellman-ford算法(判断有没有负环)

    #include <iostream> #include <vector> #include<string> #include<cstring> usi ...

  6. SPFA - Luogu 3385 【模板】负环

    [模板]负环 描述 找负环 输入 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个顶点,M条边 接下来M行,每行三个整数a b w,表示a->b有一条权值为w ...

  7. poj 3259 Wormholes : spfa 双端队列优化 判负环 O&lpar;k&ast;E&rpar;

    /** problem: http://poj.org/problem?id=3259 spfa判负环: 当有个点被松弛了n次,则这个点必定为负环中的一个点(n为点的个数) spfa双端队列优化: 维 ...

  8. poj3259 Wormholes【Bellman-Ford或 SPFA判断是否有负环 】

    题目链接:poj3259 Wormholes 题意:虫洞问题,有n个点,m条边为双向,还有w个虫洞(虫洞为单向,并且通过时间为倒流,即为负数),问你从任意某点走,能否穿越到之前. 贴个SPFA代码: ...

  9. POJ3259Wormholes(判断是否存在负回路)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 38300   Accepted: 14095 Descr ...

随机推荐

  1. django 强制登录最佳实践

    参考: https://python-programming.courses/recipes/django-require-authentication-pages/ 即通过中间件来做AOP拦截.不用 ...

  2. 打完补丁后测试db&lowbar;link对SCN的影响

    环境:11.2.0.4.0 升 11.2.0.4.8 后测试 背景:oracle 的db_link会导致实例间SCN同步,SCN增长速度过快则会产生错误: 方案:oracle官方推荐升级版本,但升级之 ...

  3. BitMask 使用参考

    对于 Java 类应用,内存方面需要注意: 不要占用大量内存,否则可用内存少:触发 GC 或 OutOfMemoryError: 不要频繁创建对象,频繁内存分配,触发 GC. 对于枚举和常量: 使用枚 ...

  4. C语言函数及变量的声明与定义的区别

    变量: 1.声明变量不需要建立存储空间,如:extern int a; 2.定义变量需要建立存储空间,如:int a:或者 int b=10:无论变量是否赋值,只要定义它,即占用空间. 3.int a ...

  5. Python读写文件的几种方式

    一.pandas pandas模块是数据分析的大杀器,它使得对于文件相关的操作变得简单. 看一下它的简单使用 import pandas as pd # 读取 df = pd.read_csv('al ...

  6. P1282 多米诺骨牌

    P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S ...

  7. http&colon;&sol;&sol;blog&period;csdn&period;net&sol;a9529lty&sol;article&sol;details&sol;6454145

    http://blog.csdn.net/a9529lty/article/details/6454145

  8. 在 Flash ActionScript 2&period;0 中调用 Javascript 方法

    本篇文章由:http://xinpure.com/call-the-javascript-method-in-flash-actionscript-2-0/ 在 Flash ActionScript ...

  9. javascript继承—prototype最优两种继承(空函数和循环拷贝)

    一.利用空函数实现继承 参考了文章javascript继承-prototype属性介绍(2) 中叶小钗的评论,对这篇文章中的方案二利用一个空函数进行修改,可以解决创建子类对象时,父类实例化的过程中特权 ...

  10. python的协程和&lowbar;IO操作

    协程Coroutine: 协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行. 注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点 ...