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;
}
原文地址:https://www.cnblogs.com/kafuuchino/p/9684058.html