差分约束模板

题目

差分约束模板

时间复杂度:\(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;
}
posted @ 2026-08-12 19:06  decentz  阅读(10)  评论(0)    收藏  举报