【NOIP2009提高组T3】最优贸易-双向SPFA
题目大意:有N个城市,它们之间有M条道路相连,可能是单向道路或双向道路。对于同一种商品,在每个城市的价格不一定相同,一个商人在1号城市出发,要走到n号城市,他想在路径中某一个城市买入,并在之后的某一个城市卖出以赚取差价(差价等于卖出的城市中的价格减去买入的城市中的价格),求出这个商人可以赚到的最大差价。
做法:在存储图的同时存储一个与这个图相反的图(单向路径的指向相反,双向路径不受影响),对反图做一次SPFA,求出从每个点出发到终点的路径上的最大卖价sell[i](在反图中表现为终点到每个点的路径上的最大的点权),再对正图做一次SPFA,求出从起点到每个点的路径上的最小买价buy[i],最后枚举每个点,求出最大差价(sell[i]-buy[i])即可。由于点很多,边相对来说很少,所以我们使用邻接表来存储。
以下是本人代码:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
long n,m,price[100010]={0},last[100010]={0},qlast[100010]={0},total,qtotal;
long buy[100010],sell[100010],v[100010]={0};
struct
{
long p,next;
}form[1100010],qform[1100010];
void spfa()
{
long q[500010]={0},h,t;
h=1;
t=2;
q[h]=1;
v[q[h]]=1;
for(int i=1;i<=n;i++) buy[i]=999999999;
while(h!=t)
{
v[q[h]]=0;
for(int i=q[h];i!=0;i=form[i].next)
if (price[form[q[h]].p]<buy[form[i].p])
{
buy[form[i].p]=price[form[q[h]].p];
if (!v[form[i].p]) {v[form[i].p]=1;q[t]=form[i].p;t++;if (t>500001) t=1;}
}
h++;if (h>500001) h=1;
}
}
void qspfa()
{
long q[500010]={0},h,t;
h=1;
t=2;
q[h]=n;
v[q[h]]=1;
for(int i=1;i<=n;i++) sell[i]=0;
while(h!=t)
{
v[q[h]]=0;
for(int i=q[h];i!=0;i=qform[i].next)
if (price[qform[q[h]].p]>sell[qform[i].p])
{
sell[qform[i].p]=price[qform[q[h]].p];
if (!v[qform[i].p]) {v[qform[i].p]=1;q[t]=qform[i].p;t++;if (t>500001) t=1;}
}
h++;if (h>500001) h=1;
}
}
void input()
{
cin >> n >> m;
total=qtotal=n;
for(int i=1;i<=n;i++)
{
cin >> price[i];
last[i]=i;
qlast[i]=i;
form[i].p=i;
qform[i].p=i;
}
for(int i=1;i<=m*2+n;i++)
{
form[i].next=0;
qform[i].next=0;
}
for(int i=1;i<=m;i++)
{
int x,y,z;
cin >> x >> y >> z;
total++;qtotal++;
form[last[x]].next=total;
form[total].p=y;
last[x]=total;
qform[qlast[y]].next=qtotal;
qform[qtotal].p=x;
qlast[y]=qtotal;
if (z==2)
{
total++;qtotal++;
form[last[y]].next=total;
form[total].p=x;
last[y]=total;
qform[qlast[x]].next=qtotal;
qform[qtotal].p=y;
qlast[x]=qtotal;
}
}
}
void output()
{
long ans=0;
for(int i=1;i<=n;i++)
if (sell[i]-buy[i]>ans) ans=sell[i]-buy[i];
cout << ans;
}
int main()
{
input();
spfa();
qspfa();
output();
return 0;
}