差分约束模版

基础的差分约束

image

拓展

image

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e3+5;
int n,m,a,b,c,head[maxn],dis[maxn],ecnt=-1,cnt[maxn];
bool jud=1;
bool exist[maxn];
struct mint
{
	int nxt,w,v;	
}e[maxn<<1];
inline void addline(int u,int v,int w)
{
	e[++ecnt].nxt=head[u];
	e[ecnt].v=v;
	e[ecnt].w=w;
	head[u]=ecnt;	
}
int spfa()
{
	memset(dis,0x3f,sizeof(dis));
	queue<int> q;
	q.push(0);
	dis[0]=0;
	exist[0]=true;
	cnt[0]++;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		exist[u]=0;
		for(int i=head[u];~i;i=e[i].nxt)
		{
			int v=e[i].v;
			if(dis[v]>dis[u]+e[i].w)
			{
				dis[v]=dis[u]+e[i].w;
				if(!exist[v])
				{
					q.push(v);
					exist[v]=true;
					cnt[v]++;
					if(cnt[v]==n+1)
					{		
						printf("NO");
						return false;	
					}	
				}
			}
		}
	}
	return true;
}
int main()
{
	memset(head,-1,sizeof(head));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) addline(0,i,0);
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d%d",&a,&b,&c);
		addline(b,a,c);
	}
	jud=spfa();
	if(jud==1) for(int i=1;i<=n;++i) printf("%d ",dis[i]); 
	return 0;	
}

总结:

(1)思路:把一组不等式问题转化成了图论问题,然后超级源点+最短路spfa+判负环
(2)建边:由不等式的形式联想到dis[u]=min{dis[u],dis[v]+w<v,u>}

传送门:P5960 【模板】差分约束算法
ps:直接从题解转图是因为不会用markdown的特殊符号

posted @ 2021-09-04 15:41  Mint-hexagram  阅读(38)  评论(0编辑  收藏  举报