poj1201——Intervals(差分約束)

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

給出一些區間[a,b]和對應的數字c,表示要在區間內至少選c個數,求一共最少能選多少個數?
要轉化成差分約束系統,設sa是[0,a]選出的數,則sb-sa<=c。
另外0<=S(i+1)-Si<=1,即i+1這個點取了或者沒取,這樣就有三條邊了

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <cstdio>
#include <set>
#include <math.h>
#include <algorithm>
#include <queue>
#include <iomanip>
#include <map>
#include <cctype>
#define INF 0x3f3f3f3f
#define MAXN 500005
#define Mod 1000000007
using namespace std;
struct Edge
{
    int v,w,next;
};
Edge edge1[MAXN<<1];
int head1[MAXN],n,m,e,vis[MAXN],dis[MAXN];
int s,t;
void add(Edge *edge,int *head,int u,int v,int w)
{
    edge[e].v=v;
    edge[e].w=w;
    edge[e].next=head[u];
    head[u]=e;
    e++;
}
void spfa(Edge *edge,int *head,int u)
{
    memset(vis,0,sizeof(vis));
    for(int i=s;i<=t;++i)
        dis[i]=-INF;
    dis[u]=0;
    queue<int> q;
    q.push(u);
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v,w=edge[i].w;
            if(w+dis[u]>dis[v])
            {
                dis[v]=w+dis[u];
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}
int main()
{
    while(~scanf("%d",&m))
    {
        e=0;
        memset(head1,-1,sizeof(head1));
        s=INF;
        t=-INF;
        for(int i=0;i<m;++i)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(edge1,head1,a,b+1,c); //防止區間重疊
            s=min(s,a);
            t=max(t,b+1);
        }
        for(int i=s;i<t;++i)
        {
            add(edge1,head1,i,i+1,0);
            add(edge1,head1,i+1,i,-1);
        }
        spfa(edge1,head1,s);
        printf("%d\n",dis[t]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章