poj1201 Intervals

来源:互联网 发布:墨客网络 编辑:程序博客网 时间:2024/06/08 01:03

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. 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.

差分约束系统。
对于a[i..j]>=c,利用前缀和优化成s[j]-s[i-1]>=c,就可以用差分约束系统了。
注意本题的特殊性,还应该加上限制条件s[i]>=s[i-1],s[i]<=s[i-1]+1。

#include<cstdio>#include<cstring>#include<queue>using namespace std;int dis[50010],fir[50010],ne[200010],to[200010],len[200010];queue<int> q;void add(int num,int f,int t,int l){    ne[num]=fir[f];    fir[f]=num;    to[num]=t;    len[num]=l;}int main(){    int i,j,k,m,n,p,x,y,z,ans=0,u,v;    scanf("%d",&n);    for (i=1;i<=n;i++)    {        scanf("%d%d%d",&x,&y,&z);        add(i,y,x-1,-z);    }    for (i=1;i<=50000;i++)    {        add(i*2+n,i,i-1,0);        add(i*2+1+n,i-1,i,1);    }    for (i=0;i<=50000;i++)      q.push(i);    while (!q.empty())    {        u=q.front();        q.pop();        for (i=fir[u];i;i=ne[i])        {            v=to[i];            if (dis[u]+len[i]<dis[v])            {                dis[v]=dis[u]+len[i];                q.push(v);            }        }    }    for (i=0;i<=50000;i++)      ans=max(ans,-dis[i]);    printf("%d\n",ans);}
0 0