P1073 最优贸易
n 个城市间以 m 条有向道路连接, 小 T 从 1 号城市出发, 将
要去往 n 号城市.
小 T 观察到一款商品 Z 在不同的城市的价格可能不尽相同,
小 T 想要在旅行中的某一个城市购买一件商品 Z, 在另一个
城市卖出. 因为旅途劳顿, 这种买卖小 T 只打算做一次.
请问小 T 能够获得的最大收益是多少?
求点$1$到所有点的最小值,再从$n$出发判断所能够到达,取最大值即可
更新最小值方法与spfa类似
#include<bits/stdc++.h> #define N 1010101 using namespace std; int d[N],n,head[N],tot,phead[N],w[N],m,ans,tpt,dd[N]; struct node { int to,next; } e[N],p[N]; void add(int u,int v) { e[++tot].to=v,e[tot].next=head[u],head[u]=tot; } void padd(int u,int v){ p[++tpt].to=v,p[tpt].next=phead[u],phead[u]=tpt; } queue<int>Q; bool vis[N]; void spfa() { memset(vis,0,sizeof(vis)); memset(d,0x7f,sizeof(d)); Q.push(1);vis[1]=1; while(!Q.empty()){ int u=Q.front();Q.pop();vis[u]=0; for(int i=head[u];i;i=e[i].next){ int v=e[i].to,minn=min(d[u],w[u]); if(minn<d[v]){ d[v]=minn; if(!vis[v]){ Q.push(v); vis[v]=1; } } } } } void sspfa(){ memset(vis,0,sizeof(vis)); memset(dd,0x7f,sizeof(dd)); Q.push(n);vis[n]=1,dd[n]=0; while(!Q.empty()){ int u=Q.front();Q.pop();vis[u]=0; for(int i=phead[u];i;i=p[i].next){ int v=p[i].to; if(dd[v]>dd[u]+1){ dd[v]=dd[u]+1; if(!vis[v]){ Q.push(v); vis[v]=1; } } } } } int main() { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) scanf("%d",&w[i]); for(int x,y,z,i=1; i<=m; i++) { scanf("%d%d%d",&x,&y,&z); if(z==2) add(y,x); add(x,y); if(z==2) padd(x,y); padd(y,x); } spfa(); sspfa(); for(int i=1;i<=n;i++){ if(dd[i]<dd[0]) ans=max(ans,w[i]-d[i]); } printf("%d ",ans); return 0; }