题目:
题解:
在普通的spfa求最短路的基础上从每个点开始跑一次,记录一下每个点到的次数,每个点到的次数是上一点到的次数加一,如果在跑的过程中有哪一个点到的次数大于等于了总的点数则存在负环。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2010,M=10010;
int h[N],e[M],ne[M],w[M],idx;
int dist[N];
bool st[N];
int cnt[N];
int n,m;
void add(int a,int b,int c){
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
bool spfa(){
queue<int>q;
for(int i=1;i<=n;i++){
q.push(i);
st[i]=true;
}
while(q.size()){
int t=q.front();
q.pop();
st[t]=false;
for(int i=h[t];i!=-1;i=ne[i]){
int j=e[i];
if(dist[j]>dist[t]+w[i]){
dist[j]=dist[t]+w[i];
cnt[j]=cnt[t]+1;
if(cnt[j]>=n)return true;
if(st[j])continue;
st[j]=true;
q.push(j);
}
}
}
return false;
}
int main(){
scanf("%d%d",&n,&m);
memset(h,-1,sizeof h);
for(int i=0;i<m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
if(spfa())printf("Yes");
else printf("No");
return 0;
}