首页 > 代码库 > hdu 1384 Intervals (差分约束)

hdu 1384 Intervals (差分约束)

/*
给你 n 个区间 [Ai, Bi],要求从每一个区间中至少选出 Ci 个数出来组成一个序列

问:满足上面条件的序列的最短长度是多少?

则对于 不等式  f(b)-f(a)>=c,建立 一条 b 到 a 的边 权值为 c,则求的最长路 即为 最小值(集合)  

而且有隐含条件:0<=f(a)-f(a-1)<=1  则有边权关系(a,a-1,0)以及(a-1,a,-1);  
*/

/*
一般地,差分约束系统分两类:求最大差和最小差



1、求最大差

        建立形如 A-B<=C 的不等式。在原图中加入边 <B, A> 边权为 C

        对建好的图跑最短路,假设存在负环,无解(推断条件为某点被更新了 n 次)。n 为图中点的数量



2、求最小差

        建立形如 A-B>=C 的不等式,在原图中加入边 <B, A> 边权为 C

        对建好的图跑最长路,假设存在正环,无解(推断条件为某点被更新了 n 次),n 为图中点的数
*/
# include<stdio.h>
# include<algorithm>
# include<string.h>
# include<queue>
# include<stack>
# define MAX 50010
const int INF=0x3fffff;
using namespace std;
int tot;
int head[MAX];///头节点数组
int vis[MAX];
int dis[MAX];
int minn,maxx;
struct node
{
    int u;
    int v;
    int val;
    int next;
} Edge[MAX<<2];
void addEdge(int u,int v,int val)
{
    Edge[tot].u=u;
    Edge[tot].v=v;
    Edge[tot].val=val;
    Edge[tot].next=head[u];
    head[u]=tot++;
}
void Spfa()
{
    for(int i=minn; i<=maxx; i++)
        dis[i]=-INF;
    queue<int>q;
    dis[minn]=0;
    vis[minn]=1;
    q.push(minn);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u]; i!=-1; i=Edge[i].next)
        {
            int  v=Edge[i].v;
            if(dis[v]<dis[u]+Edge[i].val)
            {
                dis[v]=dis[u]+Edge[i].val;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    printf("%d\n",dis[maxx]);
    return ;
}
int main()
{
    int n,a,b,c;
    while(~scanf("%d",&n))
    {
        tot=0;
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        maxx=0;
        minn=50010;
        for(int i=0; i<n; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            b++;
            if(maxx<b)
                maxx=b;
            if(minn>a)
                minn=a;
            addEdge(a,b,c);
        }
        for(int i=minn; i<maxx; i++) ///隐含边
        {
            addEdge(i,i+1,0);
            addEdge(i+1,i,-1);
        }
        Spfa();
    }
    return 0;
}

hdu 1384 Intervals (差分约束)