zoukankan      html  css  js  c++  java
  • POJ-3159 Candies 最短路应用(差分约束)

    题目链接:https://cn.vjudge.net/problem/POJ-3159

    题意

    给出一组不等式
    求第一个变量和最后一个变量可能的最大差值
    数据保证有解

    思路

    一个不等式a-b<=c,通过移项,实际上就是满足了a<=b+c
    发现在整个约束系统中,a在下满足不等式的情况下求最大值,就是在求最短路

    然而如果直接用BellmanFord(spfa)的话,还是会超时
    这时得对Bellman做第二次优化,用stack代替queue
    但是对于更多的图中,Dijsktra依然更优,所以没有必要太过考虑这个问题?

    代码

    Dijkstra

    #include <queue>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn=3e4+20, maxm=15e4+20, INF=0x3f3f3f3f;
    typedef pair<int, int> Node;
    struct Cmp{
        bool operator () (const Node &a, const Node &b){
            return a.first>b.first;
        }
    };
    struct Edge{
        int to, dis, next;
    }edges[maxm+5];
    int head[maxn+5], size=0;
    
    void addEdge(int from, int to, int dis){
        edges[size]=Edge{to, dis, head[from]};
        head[from]=size++;
    }
    
    void init(void){
        memset(head, -1, sizeof(head));
        size=0;
    }
    
    int Bellman(int n){
        int dist[maxn+5], sta[maxn+5], top=0;//cnt[maxn+5];
        bool inq[maxn+5]={false};
        // queue<int> que;
    
        memset(dist, INF, sizeof(dist)); dist[1]=0;
        sta[top++]=1;
        while (top!=0){
            int from=sta[--top];
            inq[from]=false;
    
            for (int i=head[from]; i!=-1; i=edges[i].next){
                Edge &e=edges[i];
                int &to=e.to, &dis=e.dis;
    
                if (dist[to]<=dist[from]+dis) continue;
                dist[to]=dist[from]+dis;
    
                if (inq[to]) continue;
                sta[top++]=to; inq[to]=true;
            }
        }return dist[n];
    }
    
    int Dij(int n){
        int dist[maxn+5];
        priority_queue<Node, vector<Node>, Cmp> que;
    
        memset(dist, INF, sizeof(dist)); dist[1]=0;
        que.push(Node(dist[1], 1));
        while (que.size()){
            Node x=que.top(); que.pop();
            if (x.first!=dist[x.second]) continue;
    
            int &from=x.second;
            for (int i=head[from]; i!=-1; i=edges[i].next){
                Edge &e=edges[i];
                int &to=e.to, &dis=e.dis;
    
                if (dist[to]<=dist[from]+dis) continue;
                dist[to]=dist[from]+dis;
                que.push(Node(dist[to], to));
            }
        }return dist[n];
    }
    
    int main(void){
        int n, m, from, to, dis;
    
        init();
        scanf("%d%d", &n, &m);
        for (int i=0; i<m; i++){
            scanf("%d%d%d", &from, &to, &dis);
            addEdge(from, to, dis);
        }printf("%d
    ", Dij(n));//Bellman(n));
    
        return 0;
    }
    
    Time Memory Length Lang Submitted
    532ms 2568kB 1960 G++ 2018-05-27 00:47:58

    BellmanFord

    #include <queue>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn=3e4+20, maxm=15e4+20, INF=0x3f3f3f3f;
    struct Edge{
        int to, dis, next;
    }edges[maxm+5];
    int head[maxn+5], size=0;
    
    void addEdge(int from, int to, int dis){
        edges[size]=Edge{to, dis, head[from]};
        head[from]=size++;
    }
    
    void init(void){
        memset(head, -1, sizeof(head));
        size=0;
    }
    
    int Bellman(int n){
        int dist[maxn+5], sta[maxn+5], top=0;//cnt[maxn+5];
        bool inq[maxn+5]={false};
        // queue<int> que;
    
        memset(dist, INF, sizeof(dist)); dist[1]=0;
        sta[top++]=1;
        while (top!=0){
            int from=sta[--top];
            inq[from]=false;
    
            for (int i=head[from]; i!=-1; i=edges[i].next){
                Edge &e=edges[i];
                int &to=e.to, &dis=e.dis;
    
                if (dist[to]<=dist[from]+dis) continue;
                dist[to]=dist[from]+dis;
    
                if (inq[to]) continue;
                sta[top++]=to; inq[to]=true;
            }
        }return dist[n];
    }
    
    int main(void){
        int n, m, from, to, dis;
    
        init();
        scanf("%d%d", &n, &m);
        for (int i=0; i<m; i++){
            scanf("%d%d%d", &from, &to, &dis);
            addEdge(from, to, dis);
        }printf("%d
    ", Bellman(n));
    
        return 0;
    }
    
    Time Memory Length Lang Submitted
    485ms 2108kB 1220 G++ 2018-05-27 00:39:53
  • 相关阅读:
    STM32之滴答定时器
    串口--USART1
    风扇--PWM控制
    触摸屏移植Emwin
    emwin--GUI
    extern
    STM32之定时器时间计算
    stm32之定时器
    stm32之PWM
    stm32之SPI
  • 原文地址:https://www.cnblogs.com/tanglizi/p/9124091.html
Copyright © 2011-2022 走看看