POJ1330
分析
lca模板题,数组开小了找了一个多小时
#include<iostream> #include<cstdio> #include<cmath> #include<vector> #define ll long long using namespace std; const int maxn = 1e5+7; int d[maxn],fa[maxn][32]; vector<int>g[maxn]; bool vv[maxn]; bool vis[maxn]; int n,t,u,v; void init() { //d[1]=1; for(int i=1;i<=n;i++) vis[i]=false,vv[i]=false,g[i].clear(); } void dfs(int u) // dfs预处理出每个节点的深度 { vis[u]=1; for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(!vis[v]) { d[v]=d[u]+1; // cout<<v<<' '<<d[v]<<endl; dfs(v); } } } void bz() { // cout<<fa[16][0]<<endl; for(int j=1;j<=30;j++) for(int i=1;i<=n;i++) { fa[i][j]=fa[fa[i][j-1]][j-1]; } } int LCA(int u,int v) { if(d[u]<d[v]) swap(u,v); int dc=d[u]-d[v]; for(int i=0;i<30;i++){ if((1<<i)&dc) u=fa[u][i]; } if(u==v) return u; for(int i=30;i>=0;i--) { if(fa[u][i] != fa[v][i]) { u=fa[u][i]; v=fa[v][i]; } } u=fa[u][0]; return u; } int main() { scanf("%d",&t); while(t--) { scanf("%d", &n); init(); for(int i=1;i<=n-1;i++) { scanf("%d%d", &u, &v); fa[v][0]=u; vv[v]=1; g[u].push_back(v); g[v].push_back(u); } int st; for(int i=1;i<=n;i++) if(!vv[i]) st=i; fa[st][0]=st; d[st]=0; dfs(st); bz(); scanf("%d%d", &u, &v); printf("%d ", LCA(u,v)); } return 0; }