洛谷——P1073 最优贸易

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\n",ans);
    return 0;
}

 

posted @ 2018-10-04 08:47  清风我已逝  阅读(126)  评论(0编辑  收藏  举报