差分约束系统(poj-1201)

1、内容:是解决多个一元N次不等式组(包含n个变量X1~Xn)和m个约束条件,没个约束条件都是由两个变量的差值决定的;

eg:Xi-Xj<=Ck;求一组解X1=a,X2=a2……Xn=an;

2、求解思路:将不等式Xi-Xj<=Ck视为松弛操作,dis[y]<=dis[x]+ci;进而将问题转化为两个点之间的距离的问题,将xi,xj视为一个点,Xi-Xj>=Ck视为从Xi到Xj的两个点之间的一条有向边,最后转换为单元最短路径处理。

eg:

poj-1201

要求满足要求的最少整数的个数,即求最少有多少个整数满足区间的条件,就是求最短路径,之后用sfpa算方来求。

#include<stack>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 50500;
const int INF = 99999999;
bool vis[maxn];
int head[maxn],dis[maxn];
int n,cnt,mi,mx;
struct Node{
	int next,v,w;
};
Node p[maxn*3];
void add(int u,int v,int w)
{
	p[cnt].next=head[u];
	p[cnt].v=v;
	p[cnt].w=w;
	head[u]=cnt++;
}

int spfa(int v0)
{
	for(int i=mi;i<=mx;i++) dis[i]=-INF;
	int top=0;
	queue <int> q;
	dis[v0]=0;
	memset(vis,false,sizeof(vis));
	vis[v0]=true;
	q.push(v0);
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		vis[u]=false;
		for(int i=head[u];i!=-1;i=p[i].next)
		{
			int v=p[i].v;
			int w=p[i].w;
			if(dis[v]<dis[u]+w)
			{
				dis[v]=dis[u]+w;
				if(vis[v]==0)
				{
					q.push(v);
					vis[v]=true; 
				}
			}
		}
	}
	return dis[mx];
}

int main(void)
{
	int u,v,w;
	while(~scanf("%d",&n))
	{
		cnt=1;
		memset(head,-1,sizeof(head));
		mi=INF;
		mx=-1;
		for(int i=0;i<n;i++)
		{
			scanf("%d %d %d",&u,&v,&w);
			add(u-1,v,w);
			mi=min(u-1,mi);
			mx=max(v,mx);
		}
		for(int i=mi;i<=mx;i++)
		{
			add(i,i+1,0);
			add(i+1,i,-1);
		}
		int ans=spfa(mi);
		printf("%d\n",ans);
	}
}

参考文章:https://blog.csdn.net/u013480600/article/details/37922977

https://blog.csdn.net/consciousman/article/details/53812818

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/82869140