题目链接:
http://poj.org/problem?id=1330
这个问题做法比较多,记录下自己的写法。
1,首先将数据存储在邻接表里,先将数据按照并查集存储,然后将叶子节点的深度全部神深搜出来,存储到深度数组中。
2,然后就是具体做法:
先判断两个数是否在一棵树的同一层上,若不是先调整到同一层上。然后将两个数据在并查集内,同时向上搜寻,直至fath[a]==fath[b];
#include<stdio.h>
#include<iostream>
using namespace std;
#include<cstring>
int head[1000101];
int fath[1000001];
int deep[1000001];
int js;
int root;
int n;
struct edge
{
int data;
int next;
} v[100001];
void add(int x,int y)
{
v[js].next = head[x];
v[js].data = y;
head[x] = js;
js++;
}
void input()
{
cin>>n;
memset(head,-1,sizeof head);
memset(fath,-1,sizeof fath);
for (int i = 1; i < n; i++)
{
int x, y;
cin >> x >> y;
add(x,y);
fath[y] = x;
}
}
void dfs(int x,int d)
{
for (int i = head[x]; i != -1; i = v[i].next)
dfs(v[i].data,d+1);
deep[x] = d;
}
void predeal()
{
for(int i=1; i<=n; i++)
if (fath[i] == -1)
{
root = i;
break;
}
dfs(root,0);
}
void solve()
{
int x, y;
cin >> x >> y;
if (deep[x] < deep[y])
{
swap(x,y);
}
while (deep[x] > deep[y])
x = fath[x];
while (x != y)
{
x = fath[x];
y = fath[y];
}
printf("%d\n",x);
}
int main()
{
int t;
cin >> t;
while (t--)
{
input();
predeal();
solve();
}
}