spfa判断负环
给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。
请你判断图中是否存在负权回路。
输入格式
第一行包含整数n和m。
接下来m行每行包含三个整数x,y,z,表示点x和点y之间存在一条有向边,边长为z。
输出格式
如果图中存在负权回路,则输出“Yes”,否则输出“No”。
数据范围
1≤n≤2000
,
1≤m≤10000
,
图中涉及边长绝对值均不超过10000。
输入样例:
3 3
1 2 -1
2 3 4
3 1 -4
输出样例:
Yes
#include<iostream> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int N=100010; int h[N],e[N],w[N],ne[N],dis[N],n,m,idx,cnt[N]; bool st[N]; queue<int>q; void add(int a, int b, int c){ e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++; } int spfa(){ for(int i=1;i<=n;i++){ st[i]=true; q.push(i); } while(q.size()){ int t=q.front(); st[t]=false; q.pop(); for(int i=h[t];~i;i=ne[i]){ int j=e[i]; if(dis[j]>dis[t]+w[i]){ dis[j]=dis[t]+w[i]; cnt[j]=cnt[t]+1; if(cnt[j]>=n)return true; if(!st[j]){ st[j]=true; q.push(j); } } } } return false; } int main(void){ cin>>n>>m; memset(h,-1,sizeof(h)); for(int i=0,a,b,c;i<m;i++){ cin>>a>>b>>c; add(a,b,c); } if(spfa())cout<<"Yes"<<endl; else cout<<"No"<<endl; }