您的位置:首页 > 其它

noip2009 最优贸易

2017-08-20 17:16 381 查看
题目实在太长,(当然大家会来到我这里肯定是看过题的)就不给出了,下面给出解题思路

这道题用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
=v
;used
=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);
}贴出美美的代码,很易懂的,谢谢了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: