算法竞赛——进阶指南——acwing 362. 区间 差分约束经典题目 好题 (差分约束总结)

差分约束存在性问题很简单,spfa判环即可。

难点在于求某个变量的最大值,或者某两个变量差的最大/最小值。

求某个变量的最大值我们可以转化为后者。即令x0=0 ,  xi-x0<=0  / xi-x0>=0;

先说下结论:

求变量差最大值,变成小于等于号,建图求最短路。

求变量差最小值,变成大于等于号,建图求最长路。

当然你可以强行给变量差加个符号,使得一定取最大/最小,使用最短路/最长路。(但一般不强行变,因为要求单源多终点时,必须保证超级源点到每个点都可达,很多情况下,强行变要连反边,使得超级源点不可达每个点。进而d[x]无意义)

 

给出若干个不等式,求  xi - xj 这个变量的最大值。  

其中有一个不等式:xi - xj <= c;  (这样能保证xj - > xi 可达,否则无意义,即可任意取值)

建出图后。

把所有不等式变化为: y <=x + c

满足最短路里的三角不等式:  d[y] <= d[x] + w

建图求出 xj - > xi 的最短路,即是所有约束xj - > xi 条件中的最小值,即能取到的最大值。

(比如还有一些限制条件,转化为了: xi - xj <= d, (d<=c),  那么最短路变成了d,即最大只能取到d,再往上取就会不满足约束条件)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 2e5+7;

int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}

int d[M],vs[M];
int n,m;
void spfa()
{
	memset(d,0x3f,sizeof(d));
	queue<int>q;
	q.push(50001);
	d[50001]=0;vs[50001]=1;
	while(q.size())
	{
		int x=q.front();q.pop();
		vs[x]=0;
		for(int i=head[x];i;i=ee[i].nxt)
		{
			int y=ee[i].to,w=ee[i].w;
	//		cout<<x<<" "<<y<<"  "<<w<<"  "<<d[x]<<"  "<<d[y]<<endl;
			if(d[y]>d[x]+w)
			{
				d[y]=d[x]+w;
				if(!vs[y])q.push(y),vs[y]=1;
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cin>>n;
  	for(int i=1;i<=n;i++)
  	{
  		int x,y,w;
  		cin>>x>>y>>w;
  		y++;
  		//y-x>=c    x<=-c+y
  		add(y,x,-w);
	}
	// d[i]-d[i-1]>=0  -> d[i-1]<=d[i]+0
	// d[i]-d[i-1]<=1  -> d[i]<=d[i-1]+1
	// d[ed]-d[0]>=0    -> d[0]<=d[ed]  求出 d[0]-d[ed] 即 -d[ed] 的最大值 
	for(int i=1;i<=50001;i++)add(i,0,0),add(i-1,i,1),add(i,i-1,0);//超级原点,目的是求每个点的最小值 
	spfa();//一定有解 ,即不存在负环 	
	cout<<-d[0]<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值