这个题要求我们寻找最多的旅费,第一次看了一个题解(一个动态规划)三四十行代码就可以写过了,但是我还不太会啊;;
所有写一个双向spfa来写这个题,正向,反向各建一个图,所以我们跑两个spfa,第一个spfa我们找到能从起点到达这个点的最小买入点;
首先买点呢我们要保证能从起点到达,并且能够到达终点,卖点也是如此,第二个spfa反向建图,跑一个最大卖出点;
最后比较我们寻找最大的旅费就好啦;
#include<bits/stdc++.h> using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } struct gg { int y,v,next; }a[1000005],b[1000005]; int n,m,p[1000005],lin1[1000005],lin2[1000005],now1,now2,x,y,z,vis1[1000005],vis2[1000005],maxx[1000050],minn[1000005]; inline void init1(int x,int y) { a[++now1].y=y; a[now1].next=lin1[x]; lin1[x]=now1; } inline void init2(int x,int y) { b[++now2].y=y; b[now2].next=lin2[x]; lin2[x]=now2; } inline void spfa1() { queue<int> q; for(int i=1;i<=n;i++) minn[i]=127000007; q.push(1); vis1[1]=1;minn[1]=p[1]; while(!q.empty()) { int x=q.front(); q.pop(),vis1[x]=0; for(int i=lin1[x];i;i=a[i].next) { int b=a[i].y; if(minn[b]>minn[x]) { minn[b]=min(minn[x],p[b]); if(!vis1[b]) q.push(b),vis1[b]=1; } } } } inline int spfa2() { queue<int> q; q.push(n); vis2[n]=1;maxx[n]=p[n]; while(!q.empty()) { int x=q.front();q.pop(),vis2[x]=0; for(int i=lin2[x];i;i=b[i].next) { int y=b[i].y; if(maxx[y]<maxx[x]) { maxx[y]=max(maxx[x],p[y]); if(!vis2[y]) q.push(y),vis2[y]=1; } } } } int main() { n=read();m=read(); for(int i=1;i<=n;i++) p[i]=read(); for(int i=1;i<=m;i++) { x=read(),y=read(),z=read(); if(z==2) { init1(x,y); init1(y,x); init2(x,y); init2(y,x); } else { init2(y,x); init1(x,y); } } spfa1(); spfa2(); int ans=0; for(int i=1;i<=n;i++) ans=max(ans,maxx[i]-minn[i]); cout<<ans<<endl; return 0; }