POJ 1716 Integer Intervals(差分约束)

来源:互联网 发布:网络侵权的声明 编辑:程序博客网 时间:2024/06/04 23:21

题意:给你一些区间,问你确定一个集合,使得这个集合和这些区间至少有两个数字相同,求这个集合最小元素个数

思路:令d[i]为0到i区间的不同元素个数,那么有d[b]-d[a-1]>=2,d[i+1]>=d[i],d[i]>=d[i+1]-1,d[i]>=d[0],然后建边跑最长路求最小值就可以了,这里区间从0开始计数,我就都++了,如果不++的话那么要变成d[b+1]-d[a]>=2,这样跑了980MS...而我这样居然只跑了500MS..


#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;#define inf -1e9const int maxn = 10005;vector<pair<int,int> >e[maxn];int d[maxn],cnt[maxn],inq[maxn],n;int spfa(int num){    memset(cnt,0,sizeof(cnt));memset(inq,0,sizeof(inq));for(int i = 0;i<=num;i++)d[i]=inf;inq[0]=1;queue<int>q;d[0]=0;q.push(0);while(!q.empty()){int u = q.front();q.pop();inq[u]=0;for(int i  =0;i<e[u].size();i++){int v = e[u][i].first;if(d[v]<d[u]+e[u][i].second){d[v]=d[u]+e[u][i].second;if(!inq[v]){inq[v]=1;q.push(v);if(++cnt[v]>n)return false;}}}}return 1;}int main(){   int num = 0;   while(scanf("%d",&n)!=EOF)   {   for(int i = 0;i<=num;i++)   e[i].clear();   num = 0;       for(int i = 1;i<=n;i++)   {   int u,v;   scanf("%d%d",&u,&v);   u++,v++;   num = max(num,v);   e[u-1].push_back(make_pair(v,2));   }   for(int i = 1;i<=num;i++)   {   e[0].push_back(make_pair(i,0));   e[i].push_back(make_pair(i+1,0));   e[i+1].push_back(make_pair(i,-1));   }   spfa(num);   printf("%d\n",d[num]);   }}


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

43 62 40 24 7

Sample Output

4


0 0
原创粉丝点击