POJ 1201 Intervals(图论-差分约束)
Intervals
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 20779 | Accepted: 7863 |
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 points and integers c1, ..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i=1,2,...,n,
writes the answer to the standard output.
Write a program that:
reads the number of intervals, their end points and integers c1, ..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i=1,2,...,n,
writes the answer to the standard output.
Input
The first line of the input contains an integer n (1 <= n <= 50000) -- the number of intervals. The following n lines describe the intervals. The (i+1)-th line of the input contains three integers ai, bi and ci separated by single spaces and such that 0 <=
ai <= bi <= 50000 and 1 <= ci <= bi - ai+1.
Output
The output contains exactly one integer equal to the minimal size of set Z sharing at least ci elements with interval [ai, bi], for each i=1,2,...,n.
Sample Input
5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
Sample Output
6
Source
题目大意:
n行。每行a,b,c,表示在区间a,b内要找c个数,问你总共至少要找多少个数?
解题思路:
差分约束系统。
在本题中。假设[a,b]中要找c个元素。那么:s[b]-s[a-1]>=c。我们能够推得:s[a-1] - s[b] <= -c
同一时候。因为每个值上最多仅仅能含有一个元素。那么:s[i] - s[i-1]<=1 ,又因为s[i] - s[i-1]>=0 推得:s[i-1] - s[i] <=0
这样:我们有了三个约束不等式:
s[a-1] - s[b] <= -c
s[i] - s[i-1]<=1
s[i-1] - s[i] <=0
于是:假设起点为from,终点为to。我们仅仅要求出:s[to] -s[from-1] >= M就能够了,因此求出 s[from-1]-s[to]<=-M,即求to 到 from-1 的最短路径,
注意:因为i<0,所以i-1可能小于0,因此所有向右平移1位。
#include <iostream> #include <queue> #include <cstdio> using namespace std; const int maxn=50000; const int inf=0x3f3f3f3f; struct edge{ int u,v,w,next; }e[maxn*10]; int head[maxn*2+10],dist[maxn*2+10],cnt; int n,from,to; void initial(){ cnt=0; from=inf,to=0; for(int i=0;i<=maxn;i++) head[i]=-1; } void adde(int u,int v,int w){ u++;v++; e[cnt].u=u,e[cnt].v=v,e[cnt].w=w,e[cnt].next=head[u],head[u]=cnt++; } void input(){ int u,v,w; //[v]-[u-1]>=w [u-1]-[v]<=-w for(int i=0;i<n;i++){ scanf("%d%d%d",&u,&v,&w); adde(v,u-1,-w); if(u<from) from=u; if(v>to) to=v; } //0<=[i]-[i-1]<=1 for(int i=from;i<=to;i++){ adde(i-1,i,1); adde(i,i-1,0); } } bool spfa(int from){ int s=from,num[maxn]; bool visited[maxn]; for(int i=0;i<=maxn;i++){ num[i]=0; dist[i]=inf; visited[i]=false; } queue <int> q; q.push(s); visited[s]=true; dist[s]=0; while(!q.empty()){ s=q.front(); q.pop(); for(int i=head[s];i!=-1;i=e[i].next){ int d=e[i].v; if(dist[d]>dist[s]+e[i].w){ dist[d]=dist[s]+e[i].w; if(!visited[d]){ visited[d]=true; q.push(d); num[d]++; if(num[d]>n) return false; } } } visited[s]=false; } return true; } void solve(){ //get [to]-[from-1]>=M; [from-1]-[to]<=-M spfa(to+1); cout<<-dist[from]<<endl; } int main(){ while(scanf("%d",&n)!=EOF){ initial(); input(); solve(); } return 0; }