[NOIP 2009]最优贸易 Spfa

来源:互联网 发布:淘宝任务发布平台 编辑:程序博客网 时间:2024/05/21 10:17

题目大意

求一条路上最大的点值之差。

正反两边spfa;orz tarjin缩点神犇

代码

#include <cstdio>#include <iostream>#include <cstring>#include <queue>#include <algorithm>using namespace std;struct Holder{    int to,next;}e1[500005],e2[500005];int head1[100005],head2[100005],vis1[100005],vis2[100005],imin[100005],imax[100005];int n,m,cost[100005],ans=0;int cnt1=1;void Add1(int u,int v){    e1[cnt1].to=v;    e1[cnt1].next=head1[u];    head1[u]=cnt1++;}int cnt2=1;void Add2(int u,int v){    e2[cnt2].to=v;    e2[cnt2].next=head2[u];    head2[u]=cnt2++;}int Spfa1(){    queue<int> Q;    Q.push(1);vis1[1]=1;imin[1]=cost[1];    while(!Q.empty()){        int now=Q.front();Q.pop();vis1[now]=1;        for(int i=head1[now];i;i=e1[i].next){            int v=e1[i].to;            imin[v]=min(cost[v],imin[now]);            if(!vis1[v]){                Q.push(v);            }                   }    }}int Spfa2(){    queue<int> Q;    Q.push(n);vis2[n]=1;imax[n]=cost[n];    while(!Q.empty()){        int now=Q.front();Q.pop();vis2[now]=1;        for(int i=head2[now];i;i=e2[i].next){            int v=e2[i].to;            imax[v]=max(imax[now],cost[v]);            if(!vis2[v]){                Q.push(v);              }                   }    }}void Initialize(){    memset(vis1,0,sizeof(vis1));    memset(vis2,0,sizeof(vis2));    memset(head1,0,sizeof(head1));    memset(head2,0,sizeof(head2));    memset(imin,127,sizeof(imin));    memset(imax,0,sizeof(imax));}int main(){    Initialize();    cin>>n>>m;    for(int i=1;i<=n;i++){        scanf("%d",&cost[i]);    }    for(int i=1;i<=m;i++){        int u,v,z;        scanf("%d%d%d",&u,&v,&z);        if(z==2){            Add1(u,v);            Add1(v,u);            Add2(u,v);            Add2(v,u);        }else if(z==1){            Add1(u,v);            Add2(v,u);        }    }    Spfa1();    Spfa2();    for(int i=1;i<=n;i++){        ans=max(ans,imax[i]-imin[i]);    }    cout<<ans<<endl;}
0 0