luogu1073 【noip2009提高】最优贸易(spfa)

来源:互联网 发布:面包板与单片机的连接 编辑:程序博客网 时间:2024/05/17 03:36

首先最大差价,一定是1到i点路径上的最小值与i到n路径上的最大值的差值。怎么求1到i路径上的最小值呢?利用spfa求出1到各点的路径上最小值即可。那i到n呢?我们把所有边都反向了,重新建图,以n为源点跑spfa,更新最大值。这样还顺便检验了1到i到n的连通性

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define N 100010#define M 500010#define inf 0x3f3f3f3finline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x*f;}struct edge{    int to,from,next1,next2;}data[M<<1];int n,m,a[N],mn[N],mx[N],h1[N],h2[N],num=0;bool f[N];void spfa1(){    std::queue<int>q;    memset(mn,0x3f,sizeof(mn));    mn[1]=a[1];q.push(1);f[1]=1;    while(!q.empty()){        int x=q.front();q.pop();f[x]=0;        for(int i=h1[x];i;i=data[i].next1){            int y=data[i].to;            if(mn[x]<mn[y]){                mn[y]=std::min(mn[x],a[y]);                if(!f[y]) q.push(y);f[y]=1;            }        }    }}void spfa2(){    std::queue<int>q;    memset(mx,0,sizeof(mx));    mx[n]=a[n];q.push(n);f[n]=1;    while(!q.empty()){        int x=q.front();q.pop();f[x]=0;        for(int i=h2[x];i;i=data[i].next2){            int y=data[i].from;            if(mx[x]>mx[y]){                mx[y]=std::max(mx[x],a[y]);                if(!f[y]) q.push(y);f[y]=1;            }        }    }}int main(){//  freopen("a.in","r",stdin);    n=read();m=read();for(int i=1;i<=n;++i) a[i]=read();    while(m--){        int x=read(),y=read(),op=read();        data[++num].from=x;data[num].to=y;        data[num].next1=h1[x];h1[x]=num;        data[num].next2=h2[y];h2[y]=num;        if(op==1) continue;        data[++num].from=y;data[num].to=x;        data[num].next1=h1[y];h1[y]=num;        data[num].next2=h2[x];h2[x]=num;    }    spfa1();spfa2();    int ans=0;    for(int i=1;i<=n;++i)        if(mx[i]-mn[i]>ans) ans=mx[i]-mn[i];    printf("%d\n",ans);    return 0;}
原创粉丝点击