SPFA判断负环
哇这道题我真的是被机惨了。。。
太真实了。。
#include<bits/stdc++.h> #define R register int using namespace std; const int N=2005,inf=0x3f3f3f3f,M=10005; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') if(ch=='-') f=-1,ch=getchar(); while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f; } int head[N],Next[M],val[M],go[M],dis[N]; int tot,n,m,cnt[N]; bool book[N]; inline void add(int x,int y,int z) { Next[++tot]=head[x]; val[tot]=z; go[tot]=y; head[x]=tot; } inline bool SPFA() { //memset(cnt,1,sizeof(cnt)); memset(dis,0x3f,sizeof(dis)); //memset(book,1,sizeof(book)); queue<int> Q; for(R i=1;i<=n;i++) { book[i]=1; Q.push(i); }//因为本质上并不是要求最短路,而是判断负环,所以事实上要先将所有的点都入队。 dis[1]=0; //book[1]=true; while(!Q.empty()) { int u=Q.front(); Q.pop();book[u]=0; for(R i=head[u];i;i=Next[i]) { int v=go[i]; //if(book[v]) continue; if(dis[v]>dis[u]+val[i]) { dis[v]=dis[u]+val[i]; cnt[v]=cnt[u]+1;//一个点的经过次数超过n,说明有负环。 if(cnt[v]>=n) return true; if(!book[v]) book[v]=1,Q.push(v); } } } return false; } int main() { scanf("%d%d",&n,&m); for(R i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); } if(SPFA()) cout<<"Yes"; else cout<<"No"; return 0; }
注释都在代码里了