最佳贸易

         这个题要求我们寻找最多的旅费,第一次看了一个题解(一个动态规划)三四十行代码就可以写过了,但是我还不太会啊;;

所有写一个双向spfa来写这个题,正向,反向各建一个图,所以我们跑两个spfa,第一个spfa我们找到能从起点到达这个点的最小买入点;

首先买点呢我们要保证能从起点到达,并且能够到达终点,卖点也是如此,第二个spfa反向建图,跑一个最大卖出点;

最后比较我们寻找最大的旅费就好啦;

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
struct gg
{
    int y,v,next;
}a[1000005],b[1000005];
int n,m,p[1000005],lin1[1000005],lin2[1000005],now1,now2,x,y,z,vis1[1000005],vis2[1000005],maxx[1000050],minn[1000005];
inline void init1(int x,int y)
{
    a[++now1].y=y;
    a[now1].next=lin1[x];
    lin1[x]=now1;
}
inline void init2(int x,int y)
{
    b[++now2].y=y;
    b[now2].next=lin2[x];
    lin2[x]=now2;
}
inline void spfa1()
{
    queue<int> q;
    for(int i=1;i<=n;i++)
        minn[i]=127000007;
    q.push(1);
    vis1[1]=1;minn[1]=p[1];
    while(!q.empty())
    {
        int x=q.front();
        q.pop(),vis1[x]=0;
        for(int i=lin1[x];i;i=a[i].next)
        {
            int b=a[i].y;
            if(minn[b]>minn[x])
            {
                minn[b]=min(minn[x],p[b]);
                if(!vis1[b]) q.push(b),vis1[b]=1;
            }    
        }
    }
}
inline int spfa2()
{
    queue<int> q;
    q.push(n);
    vis2[n]=1;maxx[n]=p[n];
    while(!q.empty())
    {
        int x=q.front();q.pop(),vis2[x]=0;
        for(int i=lin2[x];i;i=b[i].next)
        {
            int y=b[i].y;
            if(maxx[y]<maxx[x])
            {
                maxx[y]=max(maxx[x],p[y]);
                if(!vis2[y]) q.push(y),vis2[y]=1;
            }        
        }
    }
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
        p[i]=read();
    for(int i=1;i<=m;i++)
    {
        x=read(),y=read(),z=read();
        if(z==2)
        {
            init1(x,y);
            init1(y,x);
            init2(x,y);
            init2(y,x);
        }
        else
        {
            init2(y,x);
            init1(x,y);
        }
    }
    spfa1();
    spfa2();
    int ans=0;
    for(int i=1;i<=n;i++)
        ans=max(ans,maxx[i]-minn[i]);
    cout<<ans<<endl;
    return 0;
}
View Code

原文地址:https://www.cnblogs.com/Tyouchie/p/10259368.html