闻道有先后,术业有专攻
当用来判断负环的时候,SPFA 还挺好用的
int pre[N];
void print_path(int s, int t){
if(s == t) {cout << s; return ;}
print_path(s, pre[t]);
cout <<" " << t;
}
int head[N], cnt;
struct Edge{
int from, to, nxt, c;
}e[N << 1];
void add(int u, int v, int c){
e[++cnt].from = u;
e[cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
e[cnt].c = c;
}
int dis[N], Neg[N];
bool inq[N];
int spfa(int s){
memset(Neg, 0, sizeof(Neg));
Neg[s] = 1;
for(int i = 1; i <= n; i++) dis[i] = 1e9, inq[i] = false;
dis[s] = 0;
queue<int> Q;
Q.push(s);
inq[s] = true;
while(!Q.empty()){
int u = Q.front(); Q.pop();
inq[u] = false;
for(int i = head[u]; i != 0; i = e[i].nxt){
int v = e[i].to, c = e[i].c;
if(dis[v] > dis[u] + c){
dis[v] = dis[u] + c;
pre[v] = u;
if(!inq[v]){
inq[v] = true;
Q.push(v);
Neg[v]++;
if(Neg[v] > n){
return 1;
}
}
}
}
}
return 0;
}
如果是差分约束系统的话,那么就先建超级源点 \(S_0\), 连接所有的点,且边权为 0
void solve() {
cin >> n >> m;
for(int i = 1; i <= n; i++) add(0, i, 0);
for(int i = 1; i <= m; i++){
int u, v, val;
cin >> v >> u >> val;
add(u, v, val);
}
if(spfa(0)) cout << "NO";
else{
for(int i = 1; i <= n; i++){
cout << dis[i] << " ";
}
}
}
标签:pre,图论,int,inq,差分,SPFA,dis
From: https://www.cnblogs.com/9102qyy/p/18220986