poj1716——差分约束
Integer Intervals
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 13029 | Accepted: 5516 |
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.
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
题意:给定n个区间,求一个集合,每个区间都有两个数在集合里,求集合里的数的最小个数
思路:设s(x)为0-x中集合里的数的个数,则对区间[a,b],有s(b)-s(a-1)>=2,0<=s(i+1)-s(i)<=1;移项得s(b)-s(a-1)>=2,s(i+1)-s(i)>=0,s(i)-s(i+1)>=-1,符合dist[v]>=dist[u]+e,以此条件建图并松弛,求最长路即可,改为求最短路WA,不知道为什么。。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int maxn=10010; const int INF=(1<<28); int N; int a,b; struct Edge { int u,v,w; };Edge edge[maxn*10];int e; int Min,Max; int dist[maxn]; void add_edge(int u,int v,int w) { edge[e++]={u,v,w}; } bool relax(int cur) { int tmp=dist[edge[cur].u]+edge[cur].w; if(tmp>dist[edge[cur].v]){ dist[edge[cur].v]=tmp; return true; } return false; } int bellman_ford() { memset(dist,0,sizeof(dist)); for(int i=Min;i<Max+1;i++){ bool flag=0; for(int j=0;j<e;j++){ if(relax(j)) flag=1; } if(!flag) break; } return dist[Max+1]-dist[Min]; } int main() { while(cin>>N){ e=0; Min=INF;Max=-INF; for(int i=0;i<N;i++){ scanf("%d%d",&a,&b); add_edge(a,b+1,2); if(a<Min) Min=a; if(b>Max) Max=b; } for(int i=Min;i<=Max;i++){ add_edge(i,i+1,0); add_edge(i+1,i,-1); } cout<<bellman_ford()<<endl; } return 0; }