题目来源:
http://poj.org/problem?id=1716
题目描述:
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
解题思路:
这题是差分约束的经典题,因为是闭区间,所以我们要变成左闭右开的区间,比如3,6,就是7-3>=2,addedge(3,7,2);然后因为【1,2)最多一个点,所以也要建边,然后从0到最大点跑最长路,就是答案了。。
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#define inf 0x3f3f3f3f
/*
差分约束题型分析,
求最大值,化为a-b<=c,建b到a的边权为c的边,求最短路;
求最小值,化为a-b>=c,建b到a的边权为c的边,求最长路;
存在负环,无解;
求不出最短路,则有任意解;
*/
using namespace std;
vector<pair<int,int> >E[10005];
bool vis[10005];
int dis[10005];
int main()
{
int n,end=0;
cin>>n;
for(int i=1;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(end<b+1)end=b+1;
E[a].push_back(make_pair(b+1,2));
}
for(int i=0;i<=end;i++)
{
E[i].push_back(make_pair(i+1,0));
E[i+1].push_back(make_pair(i,-1));
}
for(int i=0;i<=end;i++)
dis[i]=-inf;
queue<int>q;
q.push(0);
vis[0]=1;
dis[0]=0;
while(!q.empty())
{
int now=q.front();
q.pop();
vis[now]=0;
for(int i=0;i<E[now].size();i++)
{
int v=E[now][i].first;
if(dis[v]<dis[now]+E[now][i].second)
{
dis[v]=dis[now]+E[now][i].second;
if(vis[v])continue;
q.push(v);
vis[v]=1;
}
}
}
cout<<dis[end]<<endl;
return 0;
}