【POJ 1716】Integer Intervals(差分约束系统)

【POJ 1716】Integer Intervals(差分约束系统)

Integer Intervals

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 13425   Accepted: 5703

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 minimal number of elements in a set containing at least two different integers from each interval.

Input

The first line of the input contains the number of intervals n, 1 <= n <= 10000. Each of the following n lines contains two integers a, b separated by a single space, 0 <= a < b <= 10000. They are the beginning and the end of an
interval.

Output

Output the minimal number of elements in a set containing at least two different integers from each interval.

Sample Input

4
3 6
2 4
0 2
4 7

Sample Output

4

Source

CEOI 1997

实训回来后的一血~~

差分约束系统,走前看了点,没搞透,做完这题稍微有点明白了。

这题是差分约束系统入门题,关于差分约束系统,百度各种大牛博客讲的都很详细,简单说就是通过不等关系建立约束系统图,然后跑最短路(大于关系则跑最长路)

回到此题,题目要求找出一个最小集合S,满足对于n个范围[ai,bi],S中存在两个及两个以上不同的点在范围内

令Zi表示满足条件的情况下,0~i点至少有多少点在集合内

则Zb-Za >= 2

只有这一个条件构造出来的图可能不是完全连通的,所以需要找一些“隐含条件”

不难发现 对于相邻的点 0 <= Zi-Z(i-1) <= 1 保证关系符相同 转化为

Zi-Z(i-1) >= 0

Z(i-1)-Zi >= -1

用这三个关系,即可构造差分约束系统,然后SPFA或者Bellman跑一趟最长路(满足所有条件)

代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>

using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 1e5;
const int mod = 1e9+7;
const double eps = 1e-8;

struct Edge
{
	int v,w,next;
};

Edge eg[233333];
int head[50050];
bool vis[50050];
int dis[50050];
int tp,st,en;

void Add(int u,int v,int w)
{
	eg[tp].v = v;
	eg[tp].w = w;
	eg[tp].next = head[u];
	head[u] = tp++;
}

int SPFA()
{
	memset(vis,0,sizeof(vis));
	memset(dis,-INF,sizeof(dis));
	queue <int> q;
	dis[st] = 0;
	vis[st] = 1;
	int u,v,w;

	q.push(st);

	while(!q.empty())
	{
		u = q.front();
		q.pop();
		vis[u] = 0;
		for(int i = head[u]; i != -1; i = eg[i].next)
		{
			v = eg[i].v;
			w = eg[i].w;
			if(dis[v] < dis[u]+w)
			{
				dis[v] = dis[u]+w;
				if(!vis[v])
				{
					q.push(v);
					vis[v] = 1;
				}
			}
		}
	}
	return dis[en];
}

int main(int argc,char **argv)
{
	int n;
	int u,v;

	while(~scanf("%d",&n))
	{
		tp = 0;
		memset(head,-1,sizeof(head));

		en = 0,st = INF;

		while(n--)
		{
			scanf("%d%d",&u,&v);
			Add(u,v+1,2);
			//最小点做起点 最大点做终点
			en = max(en,v+1);
			st = min(st,u);
		}

		for(int i = st; i < en; ++i)
		{
			Add(i,i+1,0);
			Add(i+1,i,-1);
		}
		printf("%d\n",SPFA());
	}
	return 0;
}
时间: 2024-10-14 04:28:16

【POJ 1716】Integer Intervals(差分约束系统)的相关文章

POJ - 1716 Integer Intervals(差分约束系统)

题目大意:给出N个区间,要求你找出M个数,这M个数满足在每个区间都至少有两个不同的数 解题思路:还是不太懂差分约束系统,数学不太好 借鉴了别人的思路,感觉有点DP思想 设d[i]表示[0,i-1]这个区间有d[i]个数满足要求 则给定一个区间[a,b],就有d[b + 1] - d[a] >= 2(b + 1是因为b也算在区间内) 将其转换为d[a] - d[b + 1] <= -2,这是第一个式子 接着在区间[i,i+1]中满足 d[i + 1] - d[i] >= 0 转换为 d[i

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 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的最短

POJ 1716 Integer Intervals#贪心

(- ̄▽ ̄)-* //求一个集合,这个集合与任意一个区间的交集,需至少有两个数字 //贪心过程:按n个区间的最右值从小到大对区间进行排列, //集合首先取第一个区间的最右两个数字, //到第二个区间,判断集合里的数有没有在区间里 //没有的话,就从第二个区间的最右开始往左取(cnt=0取最后两个数,cnt=1取最后一个数) #include<iostream> #include<cstdio> #include<cstring> #include<algorith

poj 1201 Intervals(差分约束系统)(困难)

Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23205   Accepted: 8764 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of intervals, their end po

POJ 3169 Layout(差分约束系统)

题目链接:http://poj.org/problem?id=3169 题意:n头牛编号为1到n,按照编号的顺序排成一列,每两头牛的之间的距离 >= 0.这些牛的距离存在着一些约束关系:1.有ML组(u, v, w)的约束关系,表示牛[u]和牛[v]之间的距离必须 <= w.2.有MD组(u, v, w)的约束关系,表示牛[u]和牛[v]之间的距离必须 >= w.问如果这n头无法排成队伍,则输出-1,如果牛[1]和牛[n]的距离可以无限远,则输出-2,否则则输出牛[1]和牛[n]之间的最

POJ1201 Intervals[差分约束系统]

Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26028   Accepted: 9952 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of intervals, their end po

【POJ1716】Integer Intervals——差分约束||贪心

题目大意:给出n个区间,现在要你找出一个点集,使得这n个区间都至少有2个元素在这个点集里面,问这个点集最少有几个点. 解法一:差分约束系统 分析:其实这道题应该说是POJ1201的简化版,不过要注意的一点是,如果你用的是SPFA,那么你的差分约束系统应该为: s[b+1]-s[a]>=2; s[b+1]-s[b]>=0; s[b]-s[b+1]>=1. 为什么下标要全部加上1呢?因为这里的a和b有可能为0,如果按照原来s[a-1]的写法会出现是s[-1]这类数组越界的问题. 代码: #i

poj 1201 Intervals 差分约束系统

题目链接:http://poj.org/problem?id=1201 题意:给定n(1<= n <= 50000)个 闭区间,每个区间后面带一个值 Ci, 问集合Z个数的最小值使得在每个区间中的数的个数 “不少于Ci”? 思路: S[i] 表示 小于等于i 的个数,这样可以直接按照输入建立不等式之后转化为有向网即可: 需要注意的是 在原始的两个不等式 S[i-1] - s[i] <= 0 和 s[i-1] - s[i] <= 1不宜在建边时就加入,这会使得有向网络中的边数达到3*

POJ 1201 &amp;&amp; HDU 1384 Intervals(差分约束系统)

题目地址:POJ 1201   HDU 1384 根据题目意思,可以列出不等式如下: Sj-Si>=c; Si-S(i-1)>=0; S(i-1)-Si>=-1; 然后用最短路spfa来解决这个不等式.用max来当源点,0为终点.最终的-d[0]就是答案. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <