POJ 1201 Intervals 差分约束

来源:互联网 发布:软件工程项目实例航空 编辑:程序博客网 时间:2024/06/05 17:07

Intervals
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 27159 Accepted: 10425
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.
Sample Input

5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
Sample Output

6

题意:
给你n个区间的限制条件a,b,c,表示[a,b]中至少要选c个不同的元素,问要满足这些限制条件最小要选多少个元素。
不难看出这是一个关于
b-a>=c 然后求满足这些不等式的最小解。
当然是用差分约束啦。
对每个限制条件从a到b连一条权值为c的边,然后跑一遍最长路。
然后兴致勃勃地码一发光荣WA掉。

首先考虑一种情况:
从[1,2]中至少选1个元素,从[2,3]中至少选一个元素,那么从[1,3]中就会至少选2个元素,但实际情况其实只需要2一个元素就够了。
其实[a,b]的元素个数即[0,b]的元素个数-[0,a-1]的元素个数。
所以限制条件可以很容易转化为:
x[b]-x[a-1]>=c 其中x[i]表示[s,i]的元素个数。即从起始到i这个位置的元素个数。

再题中所给的区间序列可能是不连续的,但数与数之间本身就具有一定的限制条件。
对i和i+1,
x]i+1]-x[i]>=0;
x[i+1]-x[i]<=1;
所以将这两个条件转化一下,连边跑最长路就可以了。

#include<cstdio>#include<cstring>#include<iostream>#include<stack>#include<queue>using namespace std;const int N = 500010;const int INF = 1<<30;int n;int s=INF,t=-INF;struct node{    int pre,v,w;}edge[N];int num=0;int head[N];void addedge(int from,int to,int w){    num++;    edge[num].pre=head[from];    edge[num].v=to;    edge[num].w=w;    head[from]=num;}bool vis[N];int dis[N];/*stack<int> q;void SPFA(){    memset(dis,-127,sizeof(dis));    memset(vis,0,sizeof(vis));    q.push(t);dis[t]=0;    while(!q.empty()){        int u=q.top();q.pop();        vis[u]=false;        for(int i=head[u];i;i=edge[i].pre){            int v=edge[i].v;            if(dis[v]<dis[u]+edge[i].w){                dis[v]=dis[u]+edge[i].w;                if(!vis[v]){                    q.push(v);                    vis[v]=true;                }            }        }    }}*/queue <int> q;void spfa(){    memset(dis,-127,sizeof(dis));//  for(int i=s;i<=t;i++)  //      dis[i]=-INF;    memset(vis,0,sizeof(vis));    q.push(s),dis[s]=0;    while(!q.empty()){        int u=q.front();q.pop();        vis[u]=false;        for(int i=head[u];i;i=edge[i].pre){            int v=edge[i].v;            if(dis[v]<dis[u]+edge[i].w){                dis[v]=dis[u]+edge[i].w;                if(!vis[v]){                    q.push(v);                    vis[v]=true;                }            }        }    }}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++){        int u,v,w;        scanf("%d%d%d",&u,&v,&w);        addedge(u-1,v,w);        if(t<v) t=v;        if(s>u-1) s=u-1;    }    for(int i=s;i<t;i++){       addedge(i+1,i,-1);       addedge(i,i+1,0);    }    //printf("%d ",t);//  SPFA();    spfa();//这个要快一点     printf("%d",dis[t]);    return 0;}
原创粉丝点击