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);
}贴出美美的代码,很易懂的,谢谢了。
这道题用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);
}贴出美美的代码,很易懂的,谢谢了。
相关文章推荐
- LG1073【NOIp2009】最优贸易 <Tarjan+DP>
- [Wikioi 1173][NOIP 2009提高组]最优贸易(疑难题)
- 【NOIP2009】【DP】【Tarjan】【SPFA】T3 最优贸易 题解
- 【noip2009】最优贸易 tarjan+拓扑+dp或spfa
- 洛谷 P1073 [NOIP2009 T3] 最优贸易
- NOIP2009 最优贸易
- luogu1073 【noip2009提高】最优贸易(spfa)
- noip2009最优贸易
- NOIP2009最优贸易——史上最详细解析
- NOIP2009 最优贸易
- [noip2009]: 最优贸易
- 【noip 2009】最优贸易
- NOIP2009 最优贸易
- [NOIP2009]潜伏者,Hankson's Problem,最优贸易,靶形数独
- Noip 2009 最优贸易 - BFS
- NOIP2009 最优贸易
- 【NOIP2009】洛谷1073 最优贸易【解法一】
- SPFA——Luogu1073 [NOIP2009]最优贸易
- NOIP2009 提高组 最优贸易 解题报告
- NOIP2009 题解 潜伏者 Hankson的趣味题 最优贸易 靶形数独