POJ 1201 Intervals (差分约束)

来源:互联网 发布:莆田云计算机房 编辑:程序博客网 时间:2024/05/17 02:41

题意:
一个整数集合Z,然后给你n个区间,每个区间有3个值,A,B,C代表在区间[A,B]上至少有C个整数属于集合Z,C可以在区间内任意取不重复的点。现在要满足所有区间的约束条件,问最少可以选多少个点。
题解:
跟POJ1716差不多。
题外话:
好狗血,这道题我用(i-1,i,0)的形式可以过,POJ1716要用(i,i+1,0)才能过,ORZ,有大佬来解答一下我的疑问吗 ?

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<queue>using namespace std;#define INF 0x3f3f3f3fconst int MAXN=5e4+7;const int MAXM=5e4*3+7;struct node{    int to,next,w;//其中edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的下一条边的存储位置,edge[i].w为边权值.}Edge[MAXM];//Edge保持m条边的个数 int head[MAXM];int dis[MAXN];int num[MAXN];bool vis[MAXN];int n,m,tot;//head和dis保持n个点 void add_edge(int a,int b,int c){    Edge[++tot].to=b;    Edge[tot].w=c;    Edge[tot].next=head[a];    head[a]=tot;}             int SPFA(int s){    queue<int>q;    int k,to,w;    memset(num,0,sizeof(num));    memset(vis,false,sizeof(vis));    for(int i=0;i<=50000;i++)    dis[i]=-INF;    dis[s]=0;    q.push(s);    vis[s]=true;//加入队列并标记    while(!q.empty())    {        k=q.front();        q.pop();        vis[k]=0;//弹出队列并取消标记        for(int i=head[k];i!=-1;i=Edge[i].next)        {            to=Edge[i].to;            w=Edge[i].w;            if(dis[k]+w>dis[to])            {                dis[to]=dis[k]+w;                if(!vis[to])//判断这个点是否在队列里面,如果不在加入队列                 {                    vis[to]=true;                    q.push(to);                    num[to]++;                    if(num[to]>n)//判断是否成环                     return -1;                }            }        }    }    return dis[m];}int main(){    while(~scanf("%d",&n))    {        memset(head,-1,sizeof(head));        tot=1,m=0;        for(int i=1;i<=50000;i++)        {            add_edge(i,i-1,-1);            add_edge(i-1,i,0);        }        for(int i=1;i<=n;i++)        {            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            m=max(m,v);            add_edge(u-1,v,w);        }        int ans=SPFA(0);        printf("%d\n",ans);    }    return 0;}
原创粉丝点击