最优贸易
题目描述
解题思路
正反跑两边 s p f a spfa spfa ,分别取最小最大值,求最大差值即可。
code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
int a[100010];
int v[100010];
int f[100010];
int nummin[100010];
int nummax[100010];
int head[100010],tot;
int head1[100010],tot1;
struct abc{
int to,next,w;
}b[1000010],b1[1000010];
void add(int x,int y,int z)
{
b[++tot]=(abc){y,head[x],z};
head[x]=tot;
}
void add1(int x,int y,int z)
{
b1[++tot1]=(abc){y,head1[x],z};
head1[x]=tot1;
}
void spfa()
{
memset(nummin,0x3f3f3f3f,sizeof(nummin));
v[1]=1;
f[1]=1;
nummin[1]=a[1];
int hd=0,tl=1;
while(hd<tl)
{
hd++;
int x=f[hd];
for(int i=head[x];i;i=b[i].next)
{
int y=b[i].to;
if(nummin[y]>min(nummin[x],b[i].w))
{
nummin[y]=min(nummin[x],b[i].w);
if(!v[y])
f[++tl]=y;
v[y]=1;
}
}
v[x]=0;
}
}
void spfa1()
{
memset(v,0,sizeof(v));
f[1]=n;
v[n]=1;
nummax[n]=a[n];
int hd=0,tl=1;
while(hd<tl)
{
hd++;
int x=f[hd];
for(int i=head1[x];i;i=b1[i].next)
{
int y=b1[i].to;
if(nummax[y]<max(nummax[x],b1[i].w))
{
nummax[y]=max(nummax[x],b1[i].w);
if(!v[y])
f[++tl]=y;
v[y]=1;
}
}
v[x]=0;
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(z==1)
{
add(x,y,a[y]);
add1(y,x,a[x]);
}
else
{
add(x,y,a[y]),add(y,x,a[x]);
add1(x,y,a[y]),add1(y,x,a[x]);
}
}
spfa();
spfa1();
int ans=0;
for(int i=2;i<n;i++)
ans=max(ans,nummax[i]-nummin[i]);
cout<<ans<<endl;
}