zoukankan      html  css  js  c++  java
  • code1173 最优贸易

    先正向从1点出发SPFA,获得min[i],就是到达i点能最低购买到的价格,(起始点到i的路上经过的最小值)

    然后反向(将图反向),从n点开始SPFA,获得max[i],就是从i点到终点能够卖出的最大的价格,(终止点到i的路上经过的最大值)

    然后就是寻找差价最大的i,输出答案即可。

    代码:

    #include<iostream>
    #include<cstring>
    #include<queue>
    #define MAXM 500005
    #define MAXN 100005
    #define INF 0x3f3f3f3f
    using namespace std;
    
    int n,m;
    struct edge{
        int to,next;
    }eg1[MAXM],eg2[MAXM];
    int head1[MAXN],head2[MAXN];
    int cnt1=0,cnt2=0;
    int num[MAXN];
    int Max[MAXN]; int Min[MAXN];
    bool vis[MAXN];
    int ans=0;
    queue<int> q;
    
    void add1(int a,int b){
        cnt1++;
        eg1[cnt1].to=b;
        eg1[cnt1].next=head1[a];
        head1[a]=cnt1;
    }
    void add2(int a,int b){
        cnt2++;
        eg2[cnt2].to=b;
        eg2[cnt2].next=head2[a];
        head2[a]=cnt2;
    }
    
    int main(){
        freopen("1.in","r",stdin);
        memset(head1,-1,sizeof(head1));
        memset(head2,-1,sizeof(head2));
        
        cin>>n>>m;
        for(int i=1;i<=n;i++)cin>>num[i];
        int a,b,c;
        for(int i=1;i<=m;i++){
            cin>>a>>b>>c;
            if(c==2){
                add1(b,a); add2(a,b);
            }
            add1(a,b); add2(b,a);
        }
        
        //spfa1
        memset(Min,0x3f,sizeof(Min));
        memset(vis,false,sizeof(vis));
        q.push(1); vis[1]=true; Min[1]=num[1];
        while(!q.empty()){
            int k=q.front(); q.pop();
            vis[k]=false;
            for(int i=head1[k];i!=-1;i=eg1[i].next){
                int u=eg1[i].to;
                if(Min[u]>Min[k]){
                    Min[u]=Min[k];
                    if(!vis[u]){
                        q.push(u);
                        vis[u]=true;
                    }
                }
                if(Min[u]>num[u]){
                    Min[u]=num[u];
                    if(!vis[u]){
                        q.push(u);
                        vis[u]=true;
                    }
                }
            }
        }
        
        //spfa2
        memset(Max,0xf3,sizeof(Max));
        memset(vis,false,sizeof(vis));
        q.push(n); vis[n]=true; Max[n]=num[n];
        while(!q.empty()){
            int k=q.front(); q.pop();
            vis[k]=false;
            for(int i=head2[k];i!=-1;i=eg2[i].next){
                int u=eg2[i].to;
                if(Max[u]<Max[k]){
                    Max[u]=Max[k];
                    if(!vis[u]){
                        q.push(u);
                        vis[u]=true;
                    }
                }
                if(Max[u]<num[u]){
                    Max[u]=num[u];
                    if(!vis[u]){
                        q.push(u);
                        vis[u]=true;
                    }
                }
            }
        }
        
        ans=0;
        for(int i=1;i<=n;i++){
            //cout<<Min[i]<<' '<<Max[i]<<endl;
            if(ans<Max[i]-Min[i]){
                ans=Max[i]-Min[i];
            }
        }
        cout<<ans<<endl;
        
        return 0;
    }

    一开始疑问没有权值spfa怎么做...学习了!

  • 相关阅读:
    对svn分支合并类型和深度的理解
    SVN中trunk,branches,tags用法详解
    如何从dump中查找ASP.NET Session的数据【转】
    c++学习笔记
    柳永教授嫖娼案庭审记录
    C++资源之不完全导引(转载)
    不讨老婆之“不亦快哉”(三十三则)(李敖)
    在一个ajax extender 工程中实现多个 ajax extender 控件的方法
    Creating a new extender(zz)
    打标签
  • 原文地址:https://www.cnblogs.com/FuTaimeng/p/5611369.html
Copyright © 2011-2022 走看看