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;
}