题目链接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. 使用spfa算法判断有没有负环

    如果存在最短路径的边数大于等于点数,就有负环 给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你判断图中是否存在负权回路. 输入格式 第一行包含整数n和m. 接下来m行每行 ...

  2. POJ 3259 Wormholes(bellman_ford,判断有没有负环回路)

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

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

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

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

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

  5. [ACM] 最短路算法整理(bellman_ford , SPFA , floyed , dijkstra 思想,步骤及模板)

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

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

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

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

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

  8. poj 3259 Wormholes : spfa 双端队列优化 判负环 O(k*E)

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

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

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

随机推荐

  1. LLDB 3.9.1 安装方法

    1. baidu到一个安装方法 进行尝试: 来源: https://zhuanlan.zhihu.com/p/40780819https://www.jianshu.com/p/f965bbba6eb ...

  2. CLOUD物料列表查询的一份跟踪

    SELECT * FROM (SELECT t0.FNUMBER fnumber, t0_L.FNAME fname, t0_L.FSPECIFICATION fspecification, t0.F ...

  3. Microsoft Visual Studio Ultimate 2013密钥

    Visual Studio Ultimate 2013 KEY(密钥):BWG7X-J98B3-W34RT-33B3R-JVYW9Visual Studio Premium 2013 KEY(密钥): ...

  4. 剑指offer(13)

    题目: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 思路: 判断当前两个根结点是否相等,如果相等,判断左右子树是否相等,如果不依次判断左右子树是否满足上 ...

  5. Object.prototype.toString.call()

    源码中有这样一段: class2type = {}, toString = class2type.toString,   function type(obj) { //obj为null或者undefi ...

  6. 如何使用命令从linux服务器下载文件到windows

    1.直接使用命令从linux下载文件到windows //登录linux服务器导出mysql数据 mysqldump -hrm-2ze8mpi5i65429l1q.mysql.rds.aliyuncs ...

  7. jmeter 启动报错:not able to find java executable or version

    1 运行cmd输入:java -version 查看 提示没有命令 2 查看环境变量path 3 执行 %JAVA_HOME% 提示找不到文件件 4 修改 文件夹名称 5 运行cmd java -ve ...

  8. Python——glob模块

    一.作用: 找到匹配上特定格式的所有文件和文件夹,跟windows的文件搜索功能差不多 二.三种匹配符 *代表0个或多个字符 ?代表一个字符 []匹配指定范围内的字符,如[0-9]匹配数 三.应用方法 ...

  9. How to remove unwant Internet Explorer Context Menu

    HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt

  10. How to install Niresh Mavericks on PC

    ed2k://|file|osx-mavericks.dmg|5653921792|f789090803e9b2c8d582813c0d4a33bf|/ diskutil list diskutil ...