• 洛谷P1073 最优贸易


    现在我才明白,自己之前做的最短路的题是有多么垃圾。

    题面很长,但其实就说的是一个中间商赚差价的故事。图论的题目一般来说建图往往是核心,而这道题的巧妙之处是在于它需要建两个图:正图和反图,正图是1-n的路径,而反图则是从n反推到1。

    题目要求我们去的在某个城市买,回来又在某个城市卖出,可以维护两个值,卖出的最大价格最大mx和最小价格mi,对于可以相互到达的城市来说,最小值和最大值都是一样的。

    所以先从1-n跑spfa,求出买入商品的最小值,又从n-1在反图上跑spfa,求出回来时卖出的最大值。最后for一遍所有的点,找到最大差价即可。

    其实想一想还是非常简单的。代码如下(参考了蒋神的代码和网上的题解):

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+7;
    const int INF=0x3f3f3f3f;
    struct node{
        int nxt;
        int to;
    }edge[maxn*2];
    struct node1{
        int nxt;
        int to;
    }edge1[maxn*2];
    int x,y,z;
    int n,m; 
    int head[maxn],cnt;
    int val[maxn];
    int mi[maxn],mx[maxn];
    bool vis[maxn];
    void add(int x,int y){
        edge[++cnt].nxt=head[x];
        edge[cnt].to=y;
        head[x]=cnt;
    }
    int head2[maxn],cnt2;
    void add2(int x,int y){
        edge1[++cnt2].nxt=head2[x];
        edge1[cnt2].to=y;
        head2[x]=cnt2;
    }
    queue<int> q;
    void spfa1(){
        for(int i=1;i<=n;i++){
            mi[i]=INF;
            vis[i]=false;
        }
        mi[1]=val[1];
        q.push(1);
        vis[1]=true;
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=head[u];i;i=edge[i].nxt){
                int v=edge[i].to;
                if(mi[v]>min(mi[u],val[v])){
                    mi[v]=min(mi[u],val[v]);
                    if(!vis[v]){
                        q.push(v);
                        vis[v]=true;
                    }
                }
            }
        }
    }
    void spfa2(){
        for(int i=1;i<=n;i++){
            mx[i]=-INF;
            vis[i]=false;
        }
        mx[n]=val[n];
        q.push(n);
        vis[n]=true;
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=head2[u];i;i=edge1[i].nxt){
                int v=edge1[i].to;
                if(mx[v]<max(mx[u],val[v])){
                    mx[v]=max(mx[u],val[v]);
                    if(!vis[v]){
                        q.push(v);
                        vis[v]=true;
                    }
                }
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&val[i]);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            if(z==1){
                add(x,y);
                add2(y,x);
            } 
            else{
                add(x,y);
                add(y,x);
                add2(x,y);
                add2(y,x); 
            }
        }
        spfa1();
        spfa2();
        int ans=0;
        for(int i=1;i<=n;i++){
            ans=max(ans,mx[i]-mi[i]);
        } 
        printf("%d
    ",ans);
        return 0;
    } 
  • 相关阅读:
    Spring Bean Expression Language(EL)
    Spring-web-security Issue (Access is denied. User must have one of the these roles: ACTUATOR)
    数据库学习笔记day04
    数据库学习笔记day03
    数据库学习笔记day01+day02
    Java学习笔记--线程day01
    Java学习笔记-Java文件操作流
    第一次月测题
    第一次月测内容疑问总结
    java核心API
  • 原文地址:https://www.cnblogs.com/LJB666/p/11173518.html
Copyright © 2020-2023  润新知