A group of ants is really proud because they built a magnificent and large colony. however, the enormous size has become a problem, because tables ants do not know the path between some parts of the colony. they desperately need your help! The colony of ants was made as a series of N anthills, connected by tunnels. the ants, obsessive as they are, numbered the anthills sequentially as they built them. the first anthill, numbered 0, did not require any tunnel, but for each of the subsequent anthills, 1 through n-1, the ants also built a single tunnel that connected the new anthill to one of the existing anthills. of course, this tunnel was enough to allow any ant to go to any previously built anthill, possibly passing through other anthills in its path, so they did not bother making extra tunnels and continued building more anthills. Your job is, given the structure of the colony and a set of queries, calculate for each query the shortest path between pairs of anthills. the length of a path is the sum of the lengths of all tunnels that need to be traveled. |
ACM icpc2010? Latin American Regional Analysis: This question is obviously a problem of the least common ancestor. During the competition, the template is knocked out, and the question is always Wa... When it is over, we find that there is no line feed output in a tragic way. #include<cstdio>#include<cstring>using namespace std;const int maxn=111111;const int maxk=111111;struct edge{ int v,next; __int64 w;}g[maxn*2],q[maxk*2];int headg[maxn],headq[maxn],parent[maxn],pos1,pos2,n,m,k,a,b,c;__int64 ans[maxk],dis[maxn];bool vis[maxn];inline void add1(int a,int b,int c){ g[pos1].next=headg[a]; g[pos1].v=b; g[pos1].w=c; headg[a]=pos1++;}inline void add2(int a,int b,int c){ q[pos2].next=headq[a]; q[pos2].v=b; q[pos2].w=c; headq[a]=pos2++;}int find(int a){ if(parent[a]==-1)return a; return parent[a]=find(parent[a]);}void tarjan(int u){ vis[u]=1; int v,i; for(i=headq[u]; i; i=q[i].next) if(vis[v=q[i].v])ans[q[i].w]=dis[u]+dis[v]-2*dis[find(v)]; for(i=headg[u]; i; i=g[i].next) if(!vis[v=g[i].v]) { dis[v]=dis[u]+g[i].w; tarjan(v); parent[v]=u; }}int main(){ while(scanf("%d",&n),n) { memset(headg,0,sizeof(headg)); memset(headq,0,sizeof(headq)); memset(vis,0,sizeof(vis)); for(int i=0; i<=n; ++i)parent[i]=-1; pos1=pos2=1; for(int i=1; i<n; ++i) { scanf("%d%d",&b,&c); add1(i,b,c); add1(b,i,c); } scanf("%d",&m); for(int i=1; i<=m; ++i) { scanf("%d%d",&a,&b); add2(a,b,i); add2(b,a,i); } dis[0]=0; tarjan(0); for(int i=1; i<m; ++i)printf("%I64d ",ans[i]); printf("%I64d\n",ans[m]); } return 0;}
|