洛谷最优贸易1073

来源:互联网 发布:yum remove php 编辑:程序博客网 时间:2024/05/17 06:12

//应当前后两边SPFA求出各点在连接起点,连接终点的路上的最小权值和最大权值,再用两者相减。

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;int n,m,tt=0,ta=0,ans=0;int w[100001],team[1000001],exist[500001],maxx[100001],minn[100001];//双SPFA。struct re//存两个相反的图。{    int w,t,next,head;}e[500001],e2[500001];void build(int x,int y){    ++ta;    e[ta].t=y;    e[ta].next=e[x].head;    e[x].head=ta;    e2[ta].t=x;    e2[ta].next=e2[y].head;    e2[y].head=ta;}int main(){    memset(minn,0x7fffffff/3,sizeof(minn));    cin>>n>>m;    for(int i=1;i<=n;i++)    {        cin>>w[i];    }    for(int i=1;i<=m;i++)    {        int a,b,c;        cin>>a>>b>>c;        if(c==1)        build(a,b);        else        {            build(a,b);build(b,a);        }    }    int head=0,tail=1;team[1]=1;minn[1]=w[1];    while(head<tail)//第一遍求个各点在起点到这个点路径中的最小值    {        head++;int u=team[head];exist[u]=0;        for(int i=e[u].head;i;i=e[i].next)        {            if(minn[e[i].t]<min(minn[u],w[e[i].t]))            {                minn[e[i].t]=min(minn[u],w[e[i].t]);                if(!exist[e[i].t])                {                    team[++tail]=e[i].t;                    exist[e[i].t]=1;                }            }        }    }    memset(team,0,sizeof(team));memset(exist,0,sizeof(exist));maxx[n]=w[n];    int headw=0,tailw=1;team[1]=n;    while(headw<tailw)//第二遍求最大值    {        headw++;int uw=team[headw];exist[uw]=0;        for(int i=e2[uw].head;i;i=e2[i].next)        {            if(maxx[e2[i].t]<max(maxx[uw],w[e[i].t]))            {                maxx[e2[i].t]=max(maxx[uw],w[e[i].t]);                if(!exist[e2[i].t])                {                    team[++tailw]=e2[i].t;                    exist[e2[i].t]=1;                }            }        }    }    for(int i=1;i<=n;i++)    {        ans=max(ans,maxx[i]-minn[i]);    }    cout<<ans;    return 0;}