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
令d[k]为从区间[0, k]中选取的元素的个数,根据题意建立差分约束系统:d[bi+1]-d[ai]>=2, 0=<d[i+1]-d[i]<=1,然后用spfa求解。
View Code
#include <stdio.h> #include <string.h> #include <queue> using namespace std; #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define N 10010 #define M 40010 #define INF 0x3fffffff int n,s,t; int d[N]; int inq[N]; int first[N],next[M],v[M],w[M]; int e; void init() { e=0; memset(first,-1,sizeof(first)); s=N; t=-N; } void insert(int a,int b,int c) { v[e]=b; w[e]=c; next[e]=first[a]; first[a]=e++; } void spfa() { queue<int> q; int a,b; memset(inq,0,sizeof(int)*(t+5)); for(int i=s;i<=t;i++) d[i]=INF; d[s]=0; inq[s]=1; q.push(s); while(!q.empty()) { a=q.front(),q.pop(); inq[a]=0; for(int i=first[a];i!=-1;i=next[i]) { b=v[i]; if(d[b]>d[a]+w[i]) { d[b]=d[a]+w[i]; if(inq[b]==0) inq[b]=1,q.push(b); } } } printf("%d\n",-d[t]); } int main() { int i,a,b; while(~scanf("%d",&n)) { init(); for(i=0;i<n;i++) { scanf("%d%d",&a,&b); s=MIN(s,a); t=MAX(t,b+1); insert(a,b+1,-2); } for(i=s;i<t;i++) insert(i,i+1,0),insert(i+1,i,1); spfa(); } return 0; }