noip2009 最优贸易

来源:互联网 发布:数据网络开关在那 编辑:程序博客网 时间:2024/05/21 09:47

题目实在太长,(当然大家会来到我这里肯定是看过题的)就不给出了,下面给出解题思路

这道题用spfa来写,具体参考黄哲威神犇;

这道题因为要得到一个最大的旅费,而这个旅费又要通过买卖水晶球来得到,所以我们肯定是要在水晶球价格低的时候买进,高的时候卖出,这个时候就需要走两遍spfa来得到买水晶球的花费和卖水晶球的收益来得到最终的答案

#include<iostream>#include<cstring>#include<cstdio>using namespace std;int n,m,sum,v[100001],last1[100001],last2[100001],mn[100001],mx[100001],d[1000001];bool used[100001];struct oo{int from,to,next1,next2;}f[1000001];void ins(int u,int v){    sum++;    f[sum].to=v;    f[sum].from=u;    f[sum].next1=last1[u];    f[sum].next2=last2[v];    last1[u]=sum;    last2[v]=sum;}int main(){    memset(mn,127,sizeof(mn));    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        scanf("%d",&v[i]);    for(int i=1;i<=m;i++)    {        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        ins(x,y);        if(z==2)ins(y,x);    }    int t=0,w=0;    d[0]=1;mn[1]=v[1];used[1]=1;    while(t<=w)    {        int p=last1[d[t]];        while(p>0)        {            if(mn[f[p].to]>mn[d[t]]||v[f[p].to]<mn[f[p].to])            {                mn[f[p].to]=min(v[f[p].to],mn[d[t]]);                if(!used[f[p].to])d[++w]=f[p].to;                used[f[p].to]=1;            }            p=f[p].next1;        }        used[d[t]]=0;        t++;    }    memset(used,0,sizeof(used));    memset(mx,-1,sizeof(mx));    d[0]=n;mx[n]=v[n];used[n]=1;t=0,w=0;    while(t<=w)    {        int p=last2[d[t]];        while(p>0)        {            if(mx[f[p].from]<mx[d[t]]||v[f[p].from]>mx[f[p].from])            {                mx[f[p].from]=max(v[f[p].from],mx[d[t]]);                if(!used[f[p].from])d[++w]=f[p].from;                used[f[p].from]=1;            }            p=f[p].next2;        }        used[d[t]]=0;        t++;    }    int ans=0;    for(int i=1;i<=n;i++)        ans=max(mx[i]-mn[i],ans);    printf("%d",ans);}
贴出美美的代码,很易懂的,谢谢了。

原创粉丝点击