BZOJ 2100: [Usaco2010 Dec]Apple Delivery spfa

由于是无向图,所以可以枚举两个终点,跑两次最短路来更新答案. 

#include <queue> 
#include <cstdio> 
#include <cstring>    
#include <algorithm>  
#define N 100006 
#define M 200007   
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;   
deque<int>q;  
int n,m,A,B,C,edges; 
int hd[N],to[M<<1],nex[M<<1],val[M<<1],d[2][M],inq[2][M];    
void addedge(int u,int v,int c) 
{    
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;   
}  
void spfa(int s,int t) 
{  
    // printf("%d\n",s);    
    memset(d[t],0x3f,sizeof(d[t])); 
    memset(inq[t],0,sizeof(inq[t]));    
    d[t][s]=0, inq[t][s]=1, q.push_back(s);          
    for(;!q.empty();) 
    {
        int u=q.front(); q.pop_front();     
        inq[t][u]=0;      
        for(int i=hd[u];i;i=nex[i]) 
        { 
            int v=to[i];            
            if(d[t][u] + val[i] < d[t][v]) 
            { 
                d[t][v] = d[t][u] + val[i];              
                if(!inq[t][v]) 
                {
                    if(q.empty()||d[t][v] < d[t][q.front()]) q.push_front(v);   
                    else q.push_back(v);    
                    inq[t][v]=1;      
                }
            }
        }
    }
}
int main() 
{  
    int i,j; 
    // setIO("input"); 
    scanf("%d%d%d%d%d",&m,&n,&A,&B,&C);     
    for(i=1;i<=m;++i) 
    {
        int a,b,c; 
        scanf("%d%d%d",&a,&b,&c), addedge(a,b,c), addedge(b,a,c);    
    }     
    spfa(B, 0);        
    // printf("%d %d\n",d[0][A],d[0][C]);       
    spfa(C, 1);       
    printf("%d\n",min(d[0][A] + d[0][C], d[1][A] + d[1][B]));  
    return 0; 
}

  

posted @ 2019-09-19 14:22  EM-LGH  阅读(106)  评论(0编辑  收藏  举报