POJ 1201 Intervals (差分约束系统)

此题是 POJ 1716的加强版。

题意:给定n个整数区间,求一整数集合,使得任意区间中至少有ci个数在集合中,求集合中最少包含的元素个数。

建立差分约束系统:d[bi+1]-d[ai]>=ci ,0<=d[i+1]-d[i]<=1,d[k]为在区间[0,k-1]中选取的元素个数。

View Code
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define N 50010
#define M 200010
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define INF 0x3fffffff
int n,s,t;
int d[N],inq[N];
int first[N],next[M],v[M],w[M],e;
void init()
{
    memset(first,-1,sizeof(first));
    e=0;
    s=N;
    t=0;
}
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,i;
    memset(inq,0,sizeof(int)*(t+5));
    for(int i=s;i<=t;i++)   d[i]=INF;
    d[s-1]=0;
    q.push(s-1);
    inq[s-1]=1;
    while(!q.empty())
    {
        a=q.front(),q.pop();
        inq[a]=0;
        for(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);
            }
        }
    }
}
int main()
{
    int i;
    int a,b,c;
    while(~scanf("%d",&n))
    {
        init();
        for(i=0;i<n;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            s=MIN(s,MIN(a,b));
            t=MAX(t,MAX(a,b));
            insert(a,b+1,-c);
        }
        s++,t++;
        for(i=s;i<t;i++)    insert(i,i+1,0),insert(i+1,i,1);
        spfa();
        printf("%d\n",-d[t]);
    }
    return 0;
}
posted @ 2012-07-24 17:24  BeatLJ  阅读(208)  评论(0编辑  收藏  举报