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;
}

 

posted @ 2021-02-03 16:30  君与  阅读(55)  评论(0编辑  收藏  举报