spfa 一个跑判定负环, 一个跑源点的最短路
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#define N 1010
#define M 100010
#define INF 0x3f3f3f3f
int n, m, s;
int dist[N];
int count[N];
int que[N], head, tail;
bool inQue[N];
int h[N], cnt;
struct edge{
int to;
int next;
int s;
}E[M];
void add(int v, int w, int s){
E[++cnt].next = h[v];
E[cnt].to = w;
E[cnt].s = s;
h[v] = cnt;
}
void spfa1(){
memset(dist, 0x3f, sizeof dist);
dist[s] = 0;
que[++tail] = s, inQue[s] = true;
while(head != tail){
int t = que[++head];
head %= N;
inQue[t] = false;
for(int i = h[t]; i != -1; i = E[i].next){
int j = E[i].to;
if(dist[j] > dist[t] + E[i].s){
dist[j] = dist[t] + E[i].s;
if(!inQue[j]){
que[++tail] = j;
tail %= N;
inQue[j] = true;
}
}
}
}
}
bool spfa2(){
head = 0, tail = 0;
memset(dist, 0, sizeof dist);
memset(inQue, false, sizeof inQue);
for(int i = 1; i <= n; i++){
que[++tail] = i;
inQue[i] = true;
}
while(head != tail){
int t = que[++head];
head %= N;
inQue[t] = false;
for(int i = h[t]; i != -1; i = E[i].next){
int j = E[i].to;
if(dist[j] > dist[t] + E[i].s){
dist[j] = dist[t] + E[i].s;
count[j] = count[t] + 1;
if(count[j] >= n) return true;
if(!inQue[j]){
que[++tail] = j;
tail %= N;
inQue[j] = true;
}
}
}
}
return false;
}
int main(){
scanf("%d %d %d", &n, &m, &s);
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i++){
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
add(a, b, c);
}
if(spfa2()) printf("-1");
else{
spfa1();
for(int i = 1; i <= n; i++)
if(dist[i] > INF / 2) printf("NoPath\n");
else printf("%d\n", dist[i]);
}
return 0;
}
判断负环的那个y总讲的不用初始化,这是为什么呢?
关注点不同吧, 求最短路是需要判断dist是否等于INF, 但是求负环的话,只需要关注路径的经过边数,因此可以省去初始化,因为dist会一直更新变小,不需要关注dist值。
明白了 , 谢谢