POJ 1716 Interger Intervals 差分约束(入门题)

题意:给出n个区间[a,b] n,a,b<=1e4,要求找到一个最小集合 使得每个区间至少有两个数在集合中.
设d[i]为0~i中有多少个元素在集合中,mn,mx分别为左右端点

则对每个i=1..n都要满足 d[b[i]]-d[a[i]-1]>=2
保证等式有意义,d[i+1]<=d[i]+1 , d[i]<=d[i+1]
全部化为小于号 d[a[i]-1]-d[b[i]]<=-2

若答案为ans 则d[mx]-d[mn-1]>=ans

把mx当作源点,求出到mn-1的最短路即为ans

由最短路的三角形不等式 d[v]<=d[u]+w 即 d[v]-d[u]<=w
则按照上面方式建图,求出最短路的同时,也满足了所有的约束条件

#include <iostream>
#include <queue>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
typedef pair<int,int> ii;
const int N=5e5+20;
const int inf=1e9;
struct node{
	int to,next,w;
}e[N];
int head[N],cnt;
void insert(int u,int v,int w)
{
	e[cnt].to=v,e[cnt].w=w,e[cnt].next=head[u];
	head[u]=cnt++;
}
int n,inq[N],d[N];
queue<int> q;
void SPFA(int s,int t)
{
	while(!q.empty())
		q.pop();
	for(int i=0;i<=s;i++)
		inq[i]=0,d[i]=inf;
	q.push(s);
	inq[s]=1,d[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop(),inq[u]=0;
		for(int i=head[u];i!=-1;i=e[i].next)
		{
			int v=e[i].to,w=e[i].w;
			if(d[v]>d[u]+w)
			{
				d[v]=d[u]+w;
				if(!inq[v])
					inq[v]=1,q.push(v);
			//	cout<<v<<‘ ‘<<d[v]<<endl;
			}
		}
	}
	cout<<d[s]-d[t]<<endl;
}
int main()
{
	int w=2,a,b;
	while(cin>>n)
	{
		//d[b]-d[a-1]>=2
		//d[a-1]<=d[b]+(-2)
		cnt=0;
		memset(head,-1,sizeof(head));
		int mx=-inf,mn=inf;
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d",&a,&b);

			insert(b+1,a,-2);
			mx=max(mx,b+1),mn=min(mn,a);
		}
		//d[i+1]<=d[i]+1
		//d[i]<=d[i+1]

		for(int i=0;i<mx;i++)
			insert(i,i+1,1),insert(i+1,i,0);
	//	cout<<mx<<‘ ‘<<mn-1<<endl;
		SPFA(mx,mn);	

	}
	return 0;
}

  

时间: 2024-08-04 00:19:27

POJ 1716 Interger Intervals 差分约束(入门题)的相关文章

差分约束入门题ZOJ2770&amp;&amp;AOJ517

http://icpc.ahu.edu.cn/OJ/Problem.aspx?id=517 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2770 重点是建图,建完图,跑一边最短路,求出最短距离就行了 具体建图见图论算法书P201 ZOJ2770 #include <cstdio> #include <cstring> #include <cmath> #include <algorith

POJ 1364 King --差分约束第一题

题意:求给定的一组不等式是否有解,不等式要么是:SUM(Xi) (a<=i<=b) > k (1) 要么是 SUM(Xi) (a<=i<=b) < k (2) 分析:典型差分约束题,变换,令Ti = SUM(Xj) (0<=j<=i).  则表达式(1)可以看做T(a+b)-T(a-1) > k,也就是T(a-1)-T(a+b) < -k,又因为全是整数,所以T(a-1)-T(a+b) <= -k-1.  同理,(2)看做T(a+b)-T(

poj 1275 Cashier Employment 差分约束

差分约束模板题,差分约束是判断联立不等式组是否有解的一种方法,建图是关键. 代码: //poj 1275 //sep9 #include <iostream> #include <queue> using namespace std; const int maxM=10024; const int maxN=32; struct Edge { int v,w,nxt; }edge[maxM]; int t[maxN],c[maxN],head[maxN],vis[maxN],inq

poj1201 Intervals——差分约束

题目:http://poj.org/problem?id=1201 差分约束裸题: 设 s[i] 表示到 i 选了数的个数前缀和: 根据题意,可以建立以下三个限制关系: s[bi] >= s[ai-1] + ci ( 1 <= i <= n) s[i] >= s[i-1] + 0 ( 1 <= i <= mx) s[i-1] >= s[i] + (-1) (1 <= i <= mx) 然后求最长路,可以发现其中的 dis 值不会多余增大,也就满足题意要

poj 3169 Layout(差分约束)

Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6549   Accepted: 3168 Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a

POJ 1201 Intervals 差分约束

http://poj.org/problem?id=1201 TLE了很久,因为用了cin..... 思路和其他差分约束差不多,http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html 如果区间[a, b]中至少有c个元素,如果用上面的博客,那么说明xa - xb >= c,但是注意这里是闭区间,xa - xb是不包括b这个点的, 就比如用了[a, b]有c个元素,[b, d]有x个,那么ans = c + x - 1个,

poj 1716 Integer Intervals

 Integer Intervals http://poj.org/problem?id=1716 Time Limit: 1000MS   Memory Limit: 10000K       Description An integer interval [a,b], a < b, is a set of all consecutive integers beginning with a and ending with b. Write a program that: finds the m

POJ 3159 Candies(差分约束+spfa+链式前向星)

题目链接:http://poj.org/problem?id=3159 题目大意:给n个人派糖果,给出m组数据,每组数据包含A,B,C三个数,意思是A的糖果数比B少的个数不多于C,即B的糖果数 - A的糖果数<=C . 最后求n 比 1 最多多多少颗糖果. 解题思路:经典差分约束的题目,具体证明看这里<数与图的完美结合——浅析差分约束系统>. 不妨将糖果数当作距离,把相差的最大糖果数看成有向边AB的权值,我们得到 dis[B]-dis[A]<=w(A,B).看到这里,我们可以联想到

「POJ1201」Intervals - 差分约束

->戳我进原题 *** Intervals Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 30393 Accepted: 11768 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of intervals, the