zoukankan      html  css  js  c++  java
  • ZOJ-1508Intervals(差分约束)

    题意:

    有一个序列,题目用n个整数组合 [ai,bi,ci]来描述它,[ai,bi,ci]表示在该序列中处于[ai,bi]这个区间的整数至少有ci个。如果存在这样的序列,请求出满足题目要求的最短的序列长度是多少。

    分析:

    dis[i]表示从0->i-1这i个数存在多少个数。

    则有dis[b+1]-dis[a]>=c;

    dis[i+1]-dis[i]>=0 && dis[i+1]-dis[i]<=1

    转换成为:

    dis[a]-dis[b+1]<=-c;

    dis[i]-dis[i+1]<=0 

    dis[i+1]-dis[i]<=1

    建图。dis[en]-dis[st]<=w.

    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    
    const int MAXN=5e4+100;
    struct Edge{
        int from,to;
        int dist;
    };
    struct BellmanFord{
        int n,m;
        vector<Edge>edges;
        vector<int>G[MAXN];
        bool inq[MAXN];
        int d[MAXN];
        int p[MAXN];
        int cnt[MAXN];
        void init(int n)
        {
            this->n=n;
            for(int i=0;i<n;i++)G[i].clear();
            edges.clear();
        }
        void AddEdge(int from,int to,int dist)
        {
            edges.push_back((Edge){from,to,dist});
            m=edges.size();
            G[from].push_back(m-1);
        }
        bool negativeCycle()
        {
            queue<int>Q;
            memset(inq,0,sizeof(inq));
            memset(cnt,0,sizeof(cnt));
            for(int i=0;i<n;i++)
            {
                  d[i]=0;inq[0]=true;Q.push(i);
            }
            while(!Q.empty())
            {
                int u=Q.front();Q.pop();
                inq[u]=false;
                for(int i=0;i<G[u].size();i++)
                {
                    Edge& e=edges[G[u][i]];
                    if(d[e.to]>d[u]+e.dist)
                    {
                        d[e.to]=d[u]+e.dist;
                        p[e.to]=G[u][i];
                        if(!inq[e.to])
                        {
                            Q.push(e.to);
                            inq[e.to]=true;
                            if(++cnt[e.to]>n)
                                return true;
                        }
                    }
                }
            }
            return false;
        }
    };
    BellmanFord solver;
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            int maxn=0;
            int minn=INF;
            int a,b,c;
            solver.init(MAXN-10);
    
            for(int i=0;i<n;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                maxn=max(maxn,b+1);
                minn=min(minn,a);
                solver.AddEdge(b+1,a,-c);
            }
            for(int i=0;i<=maxn-1;i++){
                solver.AddEdge(i+1,i,0);
                solver.AddEdge(i,i+1,1);
            }
            solver.negativeCycle();
            printf("%d
    ",solver.d[maxn]-solver.d[minn]);
        }
        return 0;
    }
  • 相关阅读:
    OK335x mksd.sh hacking
    Qt jsoncpp 对象拷贝、删除、函数调用 demo
    OK335xS 256M 512M nand flash make ubifs hacking
    Qt QScrollArea and layout in code
    JsonCpp Documentation
    Qt 4.8.5 jsoncpp lib
    Oracle数据库生成UUID
    freemarker得到数组的长度
    FreeMarker中if标签内的判断条件
    freemarker语法
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3238493.html
Copyright © 2011-2022 走看看