USACO2010 驮运

来源:互联网 发布:java开发人员要求 编辑:程序博客网 时间:2024/06/02 04:39

此题为一道SPFA的水题,对于不同的起点我们可以求出以其为源点的最短路,之后枚举每一点三段距离之和即可。

#include<cstdio>#include<queue>#include<cstring>using namespace std;typedef long long ll;const int M=4e4+5;const int inf=~0u>>1;ll b,e,p,n,m,top=0;int f[M];ll fb[M],fe[M],fn[M];struct edge{    int nex,to;}a[M*4];inline void add(int u,int v){    a[++top]=(edge){f[u],v};    f[u]=top;}inline void init(){    for(int i=1;i<=n;++i)        fb[i]=fe[i]=fn[i]=inf;    fb[1]=fe[2]=fn[n]=0;}bool inq[M];queue<int> q1;void spfa(int x){    bool flag;    memset(inq,false,sizeof(inq));    q1.push(x);    inq[x]=1;    while(!q1.empty()){        int u=q1.front();        for(int i=f[u];i;i=a[i].nex){            int v=a[i].to;            flag=false;            if(x==1){                if(fb[v]>fb[u]+1)                fb[v]=fb[u]+1,flag=true;            }            else if(x==2){                if(fe[v]>fe[u]+1)                fe[v]=fe[u]+1,flag=true;            }            else if(x==n){                if(fn[v]>fn[u]+1)                fn[v]=fn[u]+1,flag=true;            }            if(flag){                if(!inq[v]){                    inq[v]=1;                    q1.push(v);                }            }        }        q1.pop();        inq[u]=0;    }}int main(){    scanf("%lld%lld%lld%lld%lld",&b,&e,&p,&n,&m);    int x,y;    for(int i=1;i<=m;++i){        scanf("%d%d",&x,&y);        add(x,y);        add(y,x);    }    init();    spfa(1);    spfa(2);    spfa(n);    ll ans=inf;    for(int i=1;i<=n;++i) //printf("%lld %lld %lld\n",fb[i],fe[i],fn[i]);        ans=min(ans,fn[i]*p+fb[i]*b+fe[i]*e);    printf("%lld",ans);    return 0;}
原创粉丝点击