bzoj2100[Usaco2010 Dec]Apple Delivery*
bzoj2100[Usaco2010 Dec]Apple Delivery
题意:
无向图,从源点出发,去两个地方,问最短路径是多少。两个地方去的先后没有要求,且从一个地方到另一个地方不用经过源点。点数≤100000。
题解:
求源点对所有点的最短路和一个地方到所有点的最短路,比较一下即可。听说本题需要用队列优化的spfa或dijkstra才能过,本弱写了dijkstra(反正STL优先队列不要钱)。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #define inc(i,j,k) for(int i=j;i<=k;i++) 6 #define maxn 100010 7 using namespace std; 8 9 inline int read(){ 10 char ch=getchar(); int f=1,x=0; 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} 12 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 13 return f*x; 14 } 15 struct e{int t,w,n;}; e es[maxn*4]; int g[maxn],ess; 16 void pe(int f,int t,int w){ 17 es[++ess]=(e){t,w,g[f]}; g[f]=ess; 18 es[++ess]=(e){f,w,g[t]}; g[t]=ess; 19 } 20 struct nd{ 21 int d,u; 22 bool operator < (const nd &a)const{return d>a.d;} 23 }; 24 priority_queue <nd> q; int d[maxn]; bool vis[maxn]; 25 void dijkstra(int s){ 26 while(!q.empty())q.pop(); memset(d,-1,sizeof(d)); 27 memset(vis,0,sizeof(vis)); d[s]=0; q.push((nd){0,s}); 28 while(1){ 29 int x=q.top().u; while(!q.empty()&&vis[x])q.pop(),x=q.top().u; 30 if(q.empty()&&vis[x])break; vis[x]=1; 31 for(int i=g[x];i;i=es[i].n) 32 if(d[es[i].t]==-1||d[es[i].t]>d[x]+es[i].w){ 33 d[es[i].t]=d[x]+es[i].w; 34 q.push((nd){d[es[i].t],es[i].t}); 35 } 36 } 37 } 38 int p,c,pb,pa1,pa2,dis1,dis2,dis3; 39 int main(){ 40 c=read(); p=read(); pb=read(); pa1=read(); pa2=read(); 41 inc(i,1,c){int a=read(),b=read(),c=read(); pe(a,b,c);} 42 dijkstra(pb); dis1=d[pa1]; dis2=d[pa2]; dijkstra(pa1); dis3=d[pa2]; 43 if(dis1<dis2)printf("%d",dis1+dis3);else printf("%d",dis2+dis3); 44 return 0; 45 }
20160824