小Q来到了一个随机的国度。这个国度由n座城市和m条双向道路构成。因为这个国度崇尚随机,因此m条边是用随机
选择两端点的方式生成的。充满好奇的小Q想在这里进行k次随机的旅行,每次的起点和终点也是随机选择的。在每
次出发之前,他会使用导航系统计算两点间最少需要经过几条道路。请写一个程序,帮助小Q计算两点间的最短路
标签:nbsp ons eof 需要 logs back 双向 计算 span
#include<bits/stdc++.h> const int N=1e5+7; char ib[N*100],*ip=ib; int _(){ int x=0; while(*ip<48)++ip; while(*ip>47)x=x*10+*ip++-48; return x; } int n,m,k,f[N]; std::vector<int>e[N]; int ed[N][2],tk=0; int gf(int x){ while(x!=x[f])x=x[f]=x[f][f]; return x; } struct{ int q[N],ql,qr; void clr(){ql=qr=0;} void push(int x,int d){ ed[x][0]=tk; ed[x][1]=d; q[++qr]=x; } int pop(){return q[++ql];} int cnt(){return qr-ql;} }qa,qb; int que(){ int a=_(),b=_(); if(a==b)return 0; if(gf(a)!=gf(b))return -1; ++tk; qa.clr(),qb.clr(); qa.push(a,1),qb.push(b,-1); for(;;){ for(int t=qa.cnt();t;--t){ int w=qa.pop(),d=ed[w][1]+1; for(unsigned i=0;i!=e[w].size();++i){ int u=e[w][i]; if(ed[u][0]==tk){ if(ed[u][1]<0)return d-ed[u][1]-2; }else qa.push(u,d); } } for(int t=qb.cnt();t;--t){ int w=qb.pop(),d=ed[w][1]-1; for(unsigned i=0;i!=e[w].size();++i){ int u=e[w][i]; if(ed[u][0]==tk){ if(ed[u][1]>0)return ed[u][1]-d-2; }else qb.push(u,d); } } } } int main(){ fread(ib,1,sizeof(ib),stdin); n=_(),m=_(),k=_(); for(int i=1;i<=n;++i)f[i]=i,e[i].reserve(10); for(int i=0,a,b;i<m;++i){ a=_(),b=_(); e[a].push_back(b); e[b].push_back(a); f[gf(a)]=gf(b); } for(int i=1;i<=k;++i)printf("%d\n",que()); return 0; }
标签:nbsp ons eof 需要 logs back 双向 计算 span
原文地址:http://www.cnblogs.com/ccz181078/p/7691433.html