一道最短路的题,找一个买入和卖出相差最高的点即可,我们先以1为起点跑spfa,d1[x]不再表示距离而表示能够经过权值最小的节点的权值即
if(d1[y]>min(d1[x],price[y])){ d1[y]=min(d1[x],price[y]); if(!v[y]) q.push(y),v[y]=1; }
我们在建反图,对于n点再跑spfa,算出最大值即
if(d2[y]<max(d2[x],price[y])){ d2[y]=max(d2[x],price[y]); if(!v[y]) q.push(y),v[y]=1; }
最后枚举每一个节点用d2[x]-d1[x]更新最大值即可
代码
#include<bits/stdc++.h> using namespace std; const int N=100010,M=500010; int tot1,tot2,head[3][N],ver[3][M],Next[3][M]; int d1[N],d2[N],price[N]; bool v[N]; int x,y,z,n,m,ans; queue<int> q; void add1(int x,int y){ ver[1][++tot1]=y;Next[1][tot1]=head[1][x];head[1][x]=tot1; } void add2(int x,int y){ ver[2][++tot2]=y;Next[2][tot2]=head[2][x];head[2][x]=tot2; } void spfa(){ memset(d1,0x3f,sizeof(d1)); d1[1]=price[1];v[1]=1; q.push(1); while(!q.empty()){ int x=q.front();q.pop(); v[x]=0; for(int i=head[1][x];i;i=Next[1][i]){ int y=ver[1][i]; if(d1[y]>min(d1[x],price[y])){ d1[y]=min(d1[x],price[y]); if(!v[y]) q.push(y),v[y]=1; } } } memset(v,0,sizeof(v)); d2[n]=price[n];v[n]=1; q.push(n); while(!q.empty()){ int x=q.front();q.pop(); v[x]=0; for(int i=head[2][x];i;i=Next[2][i]){ int y=ver[2][i]; if(d2[y]<max(d2[x],price[y])){ d2[y]=max(d2[x],price[y]); if(!v[y]) q.push(y),v[y]=1; } } } } int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&price[i]); for(int i=1;i<=m;++i){ scanf("%d %d %d",&x,&y,&z); if(z==1) add1(x,y),add2(y,x); else{ add1(x,y);add1(y,x); add2(x,y);add2(y,x); } } spfa(); for(int i=1;i<=n;++i){ ans=max(d2[i]-d1[i],ans); } printf("%d",ans); return 0; }