AcWing 341. 最优贸易
C国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市。
任意两个城市之间最多只有一条道路直接相连。
这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向通行的道路在统计条数时也计为1条。
C国幅员辽阔,各地的资源分布情况各不相同,这就导致了同一种商品在不同城市的价格不一定相同。
但是,同一种商品在同一个城市的买入价和卖出价始终是相同的。
商人阿龙来到C国旅游。
当他得知“同一种商品在不同城市的价格可能会不同”这一信息之后,便决定在旅游的同时,利用商品在不同城市中的差价赚一点旅费。
设C国 n 个城市的标号从 1~n,阿龙决定从1号城市出发,并最终在 n 号城市结束自己的旅行。
在旅游的过程中,任何城市可以被重复经过多次,但不要求经过所有 n 个城市。
阿龙通过这样的贸易方式赚取旅费:他会选择一个经过的城市买入他最喜欢的商品——水晶球,并在之后经过的另一个城市卖出这个水晶球,用赚取的差价当做旅费。
因为阿龙主要是来C国旅游,他决定这个贸易只进行最多一次,当然,在赚不到差价的情况下他就无需进行贸易。
现在给出 n 个城市的水晶球价格,m 条道路的信息(每条道路所连接的两个城市的编号以及该条道路的通行情况)。
请你告诉阿龙,他最多能赚取多少旅费。
注意:本题数据有加强。
#include<bits/stdc++.h> using namespace std; int n,m; int g[100005]; struct oppo{ int to,nex; }rod[1000005]; int head[100005],tot,ans; void add(int from,int to) { rod[++tot].to=to; rod[tot].nex=head[from]; head[from]=tot; } int f[100005]; int MAX[100005]; void dfs(int x,int k,int now) { if(k>=f[x]&&now<=MAX[x]) return; f[x]=k; MAX[x]=now; if(x==n) ans=max(ans,now); for(int i=head[x];i;i=rod[i].nex){ int to=rod[i].to; dfs(to,min(k,g[to]),max(MAX[x],g[to]-k)); } } int main() { memset(f,10,sizeof(f)); memset(MAX,-1,sizeof(MAX)); cin>>n>>m; for(int i=1;i<=n;i++) scanf("%d",&g[i]); for(int i=1;i<=m;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b); if(c==2) add(b,a); } dfs(1,g[1],0); cout<<ans<<"\n"; return 0; }