//给一棵树,最后问两个点的lca是谁。 #include<iostream> #include<stdlib.h> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; const int maxn=10005; struct node{ int v,next; }; node edge[maxn]; int head[maxn],cnt; void add(int a,int b){ edge[cnt].v=b; edge[cnt].next=head[a]; head[a]=cnt++; } int deep[maxn<<1];//第i个访问的点的深度 int index[maxn<<1];//第i个访问的节点的编号 int first[maxn];//第i个节点最早出现的时候 int dp[maxn<<1][16]; int in[maxn]; int time; void dfs(int u,int dep){ index[++time]=u; deep[time]=dep; if(first[u]==0) first[u]=time; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; dfs(v,dep+1); index[++time]=u; deep[time]=dep; } } void rmq_init(int n){ int i,j; for(int i=1;i<=n;i++) dp[i][0]=i; for(int j=1;1<<j<=n;j++){ int k=1<<(j-1); for(int i=1;i+k<n;i++){ if(deep[dp[i][j-1]]<=deep[dp[i+k][j-1]]) dp[i][j]=dp[i][j-1]; else dp[i][j]=dp[i+k][j-1]; } } } int rmq(int a,int b){ int dis=abs(b-a)+1; int k=log(double(dis))/log(2.0); if(deep[dp[a][k]]<=deep[dp[b-(1<<k)+1][k]]){ return dp[a][k]; } else return dp[b-(1<<k)+1][k]; } int LCA(int u,int v){ return first[u]<=first[v]?index[rmq(first[u],first[v])] :index[rmq(first[v],first[u])]; } void init(){ memset(head,-1,sizeof(head)); cnt=0; memset(first,0,sizeof(first)); memset(in,0,sizeof(in)); } int main(){ int n,m,q; int root=0; int u,v,d; int T; scanf("%d",&T); while(T--){ scanf("%d",&n); int tmp=n; init(); tmp--; while(tmp--){ scanf("%d%d",&u,&v); add(u,v); in[v]++; } time=0; for(int i=1;i<=n;i++){ if(in[i]==0){ dfs(i,0); break; } } rmq_init(time); scanf("%d%d",&u,&v); printf("%d\n",LCA(u,v)); } return 0; }
版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/hitwhacmer1
时间: 2024-10-06 14:27:48