差分约束模板
差分约束模板
时间复杂度:\(O(nm)\)
#include<bits/stdc++.h>
using namespace std;
const int N=5005;
int n,m,hd[N],ver[2*N],nxt[2*N],w[2*N],tot,dis[N],cnt[N];
bool vis[N];
queue<int> q;
void add(int u,int v,int c){
ver[++tot]=v;w[tot]=c;nxt[tot]=hd[u];hd[u]=tot;
}
bool SPFA(){
memset(dis,0x3f,sizeof(dis));
dis[0]=0;q.push(0);//超级源点距离为0
while(q.size()){
int u=q.front();q.pop();
vis[u]=false;
for(int i=hd[u];i;i=nxt[i]){
int v=ver[i];
if(dis[v]>dis[u]+w[i]){
dis[v]=dis[u]+w[i];
cnt[v]=cnt[u]+1;
if(cnt[v]>=n+1) return false;//包含超级源点共n+1个点,若边数≥n+1则有负环
if(!vis[v]){
q.push(v);
vis[v]=true;
}
}
}
}
return true;//无负环,有解
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) add(0,i,0);//添加超级源点0到所有点的边(权值为0),使整个图连通(其到各点的距离就是一组可行解,通常加上一个常数平移也是解)
for(int i=1,u,v,c;i<=m;i++){
cin>>v>>u>>c;
add(u,v,c);
}
if(SPFA()){
for(int i=1;i<=n;i++) cout<<dis[i]<<' ';
}else{
cout<<"NO";
}
return 0;
}

浙公网安备 33010602011771号