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; }