http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2838
View Code
//对于x,y,z树上的位置进行分类讨论 /* z z t t /\ / /\ /\ x y t z y x z /\ / \ x y x y */ const int MM = 55555; int N, M; vector<int>edge[MM]; bool vis[MM]; int dp[MM<<2][30]; int ief,level; int E[MM<<2], L[MM<<2], H[MM<<2]; void get_data() { int i,j,k,x,y; for(i=0;i<MM;i++) edge[i].clear(); for(i=1;i<N;i++) { scanf("%d%d",&x,&y); edge[x].push_back(y), edge[y].push_back(x); } } void dfs(int u) { int i,j,k,v; E[++ief]=u; H[u]=ief; L[ief]=++level; for(i=0;i<edge[u].size();i++) { v=edge[u][i]; if(!vis[v]) { vis[v]=true; dfs(v); E[++ief]=u; L[ief]=--level; } } } void init_rmq() { int i,j,k,lim; for(i=1;i<=ief;i++) dp[i][0]=i; k=(int)(log(1.0*ief)/log(2.0)); for(i=1;i<=k;i++) { lim=ief-(1<<i)+1; for(j=1;j<=lim;j++) { if(L[dp[j][i-1]]>L[dp[j+(1<<(i-1))][i-1]]) dp[j][i]=dp[j+(1<<(i-1))][i-1]; else dp[j][i]=dp[j][i-1]; } } } int query(int x,int y) { if(x>y) swap(x,y); int k=(int)(log(y-x+1)/log(2.0)); if(L[dp[x][k]]>L[dp[y-(1<<k)+1][k]]) return dp[y-(1<<k)+1][k]; else return dp[x][k]; } void solve() { int i,j,k,x,y,z,fxy,fxz,fyz; memset(vis,false,sizeof(vis)); vis[0]=true; level=ief=0; dfs(0); init_rmq(); scanf("%d",&M); if(g>1) printf("\n"); printcase(); for(i=0;i<M;i++) { scanf("%d%d%d",&x,&y,&z); fxy=E[query(H[x],H[y])]; fxz=E[query(H[x],H[z])]; fyz=E[query(H[y],H[z])]; if(fxz==z && fyz==z) { if(fxy==z) puts("Yes"); else puts("No"); } else { if(fxz==z || fyz==z) puts("Yes"); else puts("No"); } } } int main() { // int ca; scanf("%d",&ca); while(scanf("%d",&N)!=EOF) get_data(),solve(); return 0; }