20170713

来源:互联网 发布:数据 陈中源 编辑:程序博客网 时间:2024/06/05 08:16


T2:

已知一棵 n 个节点的有根树。有 m 个询问。每个询问给出了一对节点的编号 x 和 y ,询问 x 与 y 的祖孙关系。

输入



10 
234 -1 
12 234 
13 234 
14 234 
15 234 
16 234 
17 234 
18 234 
19 234 
233 19 

234 233 
233 12 
233 13 
233 15 
233 19

输出





2
lca模板
#include<bits/stdc++.h>using namespace std;int first[40005],father[40005],n,m,x,y,ans,tot;bool vis[40005];int f[40005][21],disl[40005];struct node{int next,to;}e[80005];inline void inser(int x,int y){tot++;e[tot].next=first[x];first[x]=tot;e[tot].to=y;}inline void dfs(int root){vis[root]=true;for(int u=first[root];u;u=e[u].next){int to=e[u].to;if(!vis[to]) disl[to]=disl[root]+1,dfs(to);}}int LCA(int x,int y){if(disl[x]<disl[y]) swap(x,y);int foot=disl[x]-disl[y];for(int i=18;i>=0;--i)if(foot>=(1<<i)) foot-=(1<<i),x=f[x][i];if(x==y) return x;for(int i=18;i>=0;--i)if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];return f[x][0];}int main(){//freopen("tree.in","r",stdin);//freopen("tree.out","w",stdout);scanf("%d",&n);int root=0;for(int i=1;i<=n;++i){scanf("%d%d",&x,&y);if(y==-1) root=x;else f[x][0]=y,inser(x,y),inser(y,x);}memset(disl,0,sizeof(disl));disl[root]=1;dfs(root);for(int i=1;i<=19;++i)for(int j=1;j<=40000;++j)if(f[j][i-1]) f[j][i]=f[f[j][i-1]][i-1];scanf("%d",&m);for(int i=1;i<=m;++i){scanf("%d%d",&x,&y);int lca=LCA(x,y);if(x==y) cout<<"0"<<endl;else if(lca==x) cout<<"1"<<endl;else if(lca==y) cout<<"2"<<endl;else cout<<"0"<<endl;} return 0;}


原创粉丝点击