• P1073 最优贸易


    最短路
    (分号逗号傻傻分不清???)
    我们从起点开始沿着正向边跑一遍dijkstra,求出从起点到某个点所经过的城市中水晶球售价最小是多少
    我们从终点开始沿着反向边跑一遍dijkstra,求出从终点到某个点所经过的城市中水晶球售价最大是多少
    然后对于每个点,枚举找到差价最大的。
    end.
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cctype>
    using namespace std;
    template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
    template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
    template <typename T> inline void read(T &x){
        char c=getchar(); x=0;
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
    }
    struct data{
        int d,u;
        bool operator < (const data &tmp) const {return d>tmp.d;}
    };
    int n,m,ans,d[2][100002],val[100002];
    int cnt[2],hd[2][100002],nxt[2][1000002],ed[2][100002],poi[2][1000002];
    inline void add(int x,int y,int p){
        nxt[p][ed[p][x]]=++cnt[p]; hd[p][x]= hd[p][x] ? hd[p][x]:cnt[p];
        ed[p][x]=cnt[p]; poi[p][cnt[p]]=y;
    }
    void dijkstra_s(int p){ //从起点开始第一遍跑,找最小值
        memset(d[p],127,sizeof(d[p]));
        priority_queue <data> h;
        h.push((data){d[p][1]=val[1],1});
        while(!h.empty()){
            data x=h.top(); h.pop();
            if(x.d!=d[p][x.u]) continue;
            for(int i=hd[p][x.u];i;i=nxt[p][i])
                if(x.d<d[p][poi[p][i]]){
                    d[p][poi[p][i]]=min(x.d,val[poi[p][i]]);
                    h.push((data){d[p][poi[p][i]],poi[p][i]});
                }
        }
    }
    void dijkstra_t(int p){ //从终点开始第二遍跑,找最大值
        memset(d[p],-1,sizeof(d[p]));
        priority_queue <data> h;
        h.push((data){d[p][n]=val[n],n});
        while(!h.empty()){
            data x=h.top(); h.pop();
            if(x.d!=d[p][x.u]) continue;
            for(int i=hd[p][x.u];i;i=nxt[p][i])
                if(x.d>d[p][poi[p][i]]){
                    d[p][poi[p][i]]=max(x.d,val[poi[p][i]]);
                    h.push((data){d[p][poi[p][i]],poi[p][i]});
                }
        }
    }
    int main(){
        read(n); read(m); int q1,q2,q3;
        for(int i=1;i<=n;++i) read(val[i]);
        for(int i=1;i<=m;++i){
            read(q1); read(q2); read(q3);
            add(q1,q2,0); add(q2,q1,1); //正/反向边建两个图
            if(q3==2) add(q2,q1,0),add(q1,q2,1); //不用括号再不用逗号就GG了QAQ
        }
        dijkstra_s(0); dijkstra_t(1);
        for(int i=1;i<=n;++i) ans=max(ans,d[1][i]-d[0][i]); //找差值最大
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    常见算法之17---二叉树相等判断以及二叉树的复制
    常见算法之16---二维数组中查找元素
    常见算法之15---求N!末尾有多少个0
    常见算法之14---球放入盒问题
    常见算法之13---跳台阶问题
    常见算法之12---求a^n%p
    DB与java的关联
    重拾python
    Codeforces Round 212 Div 2 报告(以前没写完,现在也没心情补了,先就这样吧)
    交换Ctrl和Caps Lock键
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9684058.html
Copyright © 2020-2023  润新知