【洛谷P3385】【模板】负环
题目大意
给你一个图,判断有没有负环。
分析
判断负环我们一般用spfa,spfa判断负环有两种实现方法,一种是基于bfs,一种是基于dfs。
关于spfa,有篇国家集训队论文,姜碧野的《SPFA算法的优化及应用》。
知乎上有一个spfa讲的不错的,地址。
就是说基于dfs的spfa判负环要比基于bfs的要快,但是基于bfs的比基于dfs的求最短路要快。这也就是dfs和bfs的各自特点所形成的。
代码
#include<cstdio> #include<cstring> using namespace std; const int maxn=200005; inline void read(int &x){ bool flag=0; x=0; char ch=getchar(); while(ch<'0'||ch>'9'){flag=(ch=='-');ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} x=flag?~x+1:x; } int n,m,T,tot; int head[maxn],dis[maxn]; bool vis[maxn]; struct node{ int next,to,dist; }e[maxn<<1]; inline void ins(int from,int to,int dist){ e[++tot].next=head[from]; e[tot].to=to; e[tot].dist=dist; head[from]=tot; } bool spfa(int x){ vis[x]=true; for(int i=head[x];i;i=e[i].next) if(dis[e[i].to]>dis[x]+e[i].dist){ if(vis[e[i].to]) return true; dis[e[i].to]=dis[x]+e[i].dist; if(spfa(e[i].to)) return true; } return vis[x]=false; } int main(){ read(T); while(T--){ tot=0; memset(head,0,sizeof(head)); memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); read(n);read(m); for(int i=1;i<=m;++i){ int a,b,w; read(a);read(b);read(w); ins(a,b,w); if(w>=0) ins(b,a,w); } bool flag=0; for(int i=1;i<=n;++i) if(spfa(i)){ flag=true; break; } if(flag) printf("YE5\n"); else printf("N0\n"); } return 0; }
欢迎转载,转载请注明出处!