http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1684
View Code
//重新建树,求两点间最短距离 const int MM = 11111; #define inf 0x3f3f3f3f #define debug puts("wrong") typedef long long int64; int num[MM], N, tot; int chd[MM], len; //节点的儿子个数 bool vis[MM]; vector<int>edge[MM]; struct Info{int node,step;}; void get_data() { int i,j,k; scanf("%d",&N); for(i=0;i<MM;i++) edge[i].clear(); for(i=1;i<N;i++) scanf("%d",&num[i]); tot=N+1; } int dfs(int u) { int i,j,k,v,res; vis[u]=true; for(i=0;i<edge[u].size();i++) { v=edge[u][i]; if(v<=N) continue; len++; if(chd[v]==1) return v; if(!vis[v]) return dfs(v); } } queue<Info>que; int bfs(int x,int y) { if(x==y) return 0; int i,j,k,a,b; Info tmp,tt; tmp.node=x, tmp.step=0; memset(vis,false,sizeof(vis)); vis[x]=true; while(!que.empty()) que.pop(); que.push(tmp); while(!que.empty()) { tmp=que.front(); que.pop(); a=tmp.node; b=tmp.step; for(i=0;i<edge[a].size();i++) { int v=edge[a][i]; if(!vis[v]) { vis[v]=true; tt.node=v; tt.step=b+1; if(v==y) return tt.step; else que.push(tt); } } } return 0; } void slove() { int i,j,k,tmp,tt=1,x,y; memset(chd,0,sizeof(chd)); for(j=1;j<num[1];j++) { //printf("%d %d\n",tt,tot); edge[tt].push_back(tot); edge[tot].push_back(tt); chd[tt]++; tt=tot; tot++; } edge[tt].push_back(2); edge[2].push_back(tt); chd[tt]++; //printf("%d %d %d\n",chd[1],chd[7],chd[8]); for(i=2;i<N;i++) { memset(vis,false,sizeof(vis)); for(j=0;j<=N;j++) vis[j]=true; len=0; tmp=dfs(i); // printf("%d\n",tmp); if(len==num[i]-1) { edge[tmp].push_back(i+1); edge[i+1].push_back(tmp); chd[tmp]++; } else { for(j=len+1;j<num[i];j++) { edge[tmp].push_back(tot); edge[tot].push_back(tmp); chd[tmp]++; tmp=tot; tot++; } edge[tmp].push_back(i+1); edge[i+1].push_back(tmp); chd[tmp]++; } // if(i==3) printf("%d %d %d %d\n",i,tot,tmp,len); } // for(i=0;i<edge[11].size();i++) printf("%d ",edge[11][i]); printf("\n"); scanf("%d%d",&x,&y); printf("%d\n",bfs(x,y)); } int main() { int ca; scanf("%d",&ca); while(ca--) get_data(),slove(); return 0; }