差分约束学习笔记

先放出来例题传送门

给出一组包含 m 个不等式,有 n 个未知数的形如:

{xc1xc1y1xc2xc2y2xcmxcmym

的不等式组,求任意一组满足这个不等式组的解。

因为 的存在,我们很难通过常规数学方法解决这道题目。这时,我们就要运用到差分约束的方法解决。

看到 xixjy,变形为 xixj+y,可以联想到最短路松弛的条件 disvdisu+w。所以我们可以从 ji 连一条长度为 y 的边,建一个超级源点 0,跑一遍最短路,xi=disi 即为方程的一组可行解。

但众所周知,有负权环的图是没有最短路的。所以跑的时候还要判是否有负权环,有则无解。

然后就可以写出代码:

点击查看代码
int n,m,dis[N],cnt[N];
int tot,head[N];struct node{int to,nxt,cw;}e[N];
inline void add(int u,int v,int w){e[++tot]={v,head[u],w},head[u]=tot;}
queue<int> q;
void solve(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v,w;i<=m;i++){
		scanf("%d%d%d",&v,&u,&w);
		add(u,v,w);
	}
	for(int i=1;i<=n;i++)dis[i]=infi,add(0,i,0);
	q.push(0);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=head[u];i;i=e[i].nxt){
			int v=e[i].to;
			if(dis[u]+e[i].cw<dis[v]){
				dis[v]=dis[u]+e[i].cw;
				cnt[v]++;
				if(cnt[v]>n)printf("NO"),exit(0);
				q.push(e[i].to);
			}
		}
	}
	for(int i=1;i<=n;i++)printf("%d ",dis[i]);
}
signed main(){
	int t=1;
//	scanf("%d",&t);
	while(t--)solve();
}

拓展:

  • xixj  y 将两边同时乘上 1,变为 xjxiy,即从 ij 连一条长度为 y 的边。

  • xi=xj 变为 xixj0,xjxi0 即可。

posted @   yinhee  阅读(34)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示