zoukankan      html  css  js  c++  java
  • 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
    ",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;
    }
    

  • 相关阅读:
    站立会议第八天
    Servlet基础知识
    JSP基础知识
    JSP基础知识
    JDBC工具包
    JDBC
    MySQL
    ASP.NET程序代码优化的七个方面
    中小型软件项目开发一般流程建议
    理解九种图
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/6959255.html
Copyright © 2011-2022 走看看