首先判断是否有负环,由于不是从一点开始判断是否有负环,所以要把所有的点加入队列然后判断负环。然后在遍历图是不是连通
C++ 代码
#include<bits/stdc++.h>
#include<queue>
using namespace std;
const int maxn = 100010,N=1010;
int h[maxn],e[maxn],w[maxn],ne[maxn],idx;
int vis[N],d[N],cnt[N];
int n,m,st;
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){
memset(d,0x3f,sizeof d);
int s = q.front();
d[s] = 0;
vis[s] = 1;
while(q.size()){
int t = q.front();
q.pop();
vis[t] = 0;
for(int i=h[t]; i!=-1; i = ne[i]){
int j = e[i];
if(d[j] > d[t] + w[i]){
d[j] = d[t] + w[i];
cnt[j] = cnt[t] + 1;
if(cnt[j] >= n) return false;
if(!vis[j]){
q.push(j);
vis[j]=1;
}
}
}
}
return true;
}
int main(){
cin >> n >> m >> st;
memset(h,-1,sizeof h);
for(int i=0; i < m; i++){
int u,v,w;
cin >> u >> v >> w;
add(u,v,w);
}
queue<int> x;
for(int i=1; i <= n; i++){
x.push(i);
}
if(!spfa(x)){
cout << -1 << endl;
return 0;
}
queue<int> y;
y.push(st);
memset(cnt,0,sizeof cnt);
memset(vis,0,sizeof vis);
spfa(y);
for(int i=1; i <= n; i++){
if(d[i] == 0x3f3f3f3f) cout << "NoPath"<<endl;
else cout << d[i] << endl;
}
return 0;
}
请教一下,第一次 spfa 的时候 dist 不就 求出来了么 为啥 还求 第二次,而且第二次和第一次 s 又 都不变,都让 dist[s] = 0了,那么dist[1 - n] 不就是 没有负环的时候的 答案吗?