• POJ


    一道差分约束系统的经典题。

    题意:N个人,M个关系式,每个关系式给出ai,bi,ci,使得bi-ai<=ci(ai,bi代表人的编号,ci代表糖果数), 求第N个人在不打破所有关系式的前提下,最多能拿多少糖果。

    分析:可以将每个人视作点,每个关系式视作边建图。对不等式bi-ai<=ci,将ai 视作点u,bi 视作点v,则有d[v]<=d[u]+w(u, v)。其形式与最短路算法中的边松弛操作类似。

      用优先队列优化的Dijkstra跑出最短路,d[N]就是答案。

    #include<iostream>
    #include<cstring>
    #include<stdio.h>
    #include<map>
    #include<string>
    #include<algorithm>
    #include<queue>
    //#define LOCAL
    using namespace std;
    typedef long long LL;
    const int maxn =3e4+5;
    const LL INF =(1ll<<60);
    struct Edge{
        int to,next;
        LL val;
    };
    struct HeapNode{
        LL d;           //费用或路径
        int u;
        bool operator < (const HeapNode & rhs) const{return d > rhs.d;}  
    };
    struct Dijstra{
        int n,m,tot;
        Edge edges[maxn<<4];
        bool used[maxn];
        LL d[maxn];
        int head[maxn];
    
        void init(int n){
            this->n = n;
            this->tot=0;
            memset(head,-1,sizeof(head));
        }
    
        void Addedge(int u,int v ,LL dist){
            edges[tot].to = v;
            edges[tot].val = dist;
            edges[tot].next = head[u];
            head[u] = tot++;
        }
    
        void dijkstra(int s){   
            memset(used,0,sizeof(used));
            priority_queue<HeapNode> Q;
            for(int i=0;i<=n;++i)    d[i]=INF;
            d[s]=0;
            Q.push((HeapNode){0,s});
            while(!Q.empty()){
                HeapNode x =Q.top();Q.pop();
                int u =x.u;
                if(used[u]) 
                    continue;
                used[u]= true;
                for(int i=head[u];~i;i=edges[i].next){
                    Edge & e = edges[i];
                    if(d[e.to] > d[u] + e.val){
                        d[e.to] = d[u] +e.val;
                        Q.push((HeapNode){d[e.to],e.to});
                    }
                }
            }
        }
    }G;
    
    int main()
    {
        #ifdef LOCAL
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
           #endif
        int N,M,u,v;
        LL tmp;
        while(scanf("%d%d",&N,&M)==2){
            G.init(N);
            for(int i=1;i<=M;++i){
                scanf("%d%d%I64d",&u,&v,&tmp);
                G.Addedge(u,v,tmp);        //有向边
            }
            G.dijkstra(1);
            LL res=G.d[N];
            printf("%I64d
    ",res);
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    与您分享
    与您分享
    与您分享
    与您分享
    与您分享
    分享:PythonSIP 4.14.2 发布
    与您分享
    编码
    分享:C++十种方法"Hello World"
    与您分享
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9311182.html
Copyright © 2020-2023  润新知