题目链接:http://poj.org/problem?id=1330
题意:给出一颗树,最后寻问两个点的最近公共祖先。
可以用LCA来解决,没什么问题。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
const int M = 10005;
int h[M],num[M],nex[M],pos;
int father[M],ancestor[M],degree[M];
bool flag[M];
int s,t;
void init()
{
clr(degree,0);
clr(flag,false);
clr(h,-1);
pos = 0;
clr(father,-1);
}
void add(int u,int v)
{
num[pos] = v;
nex[pos] = h[u];
h[u] = pos++;
}
void make_set(int x)
{
father[x] = x;
}
int find(int x)
{
if(father[x] == x) return x;
return father[x] = find(father[x]);
}
void Union(int a,int b)
{
father[find(b)] = find(a);
}
void LCA(int u)
{
ancestor[u] = u;
make_set(u);
for(int i = h[u];i != -1;i = nex[i])
{
LCA(num[i]);
Union(num[i],u);
ancestor[ find(u) ] = u;
}
flag[u] = true;
if(s == u && flag[t])
{
cout<<ancestor[ find(t) ]<<endl;
}
if(t == u && flag[s])
{
cout<<ancestor[ find(s) ]<<endl;
}
}
int main()
{
int n,T;
cin>>T;
while(T--)
{
cin>>n;
init();
int u,v;
for(int i = 0;i < n-1;++i)
{
cin>>u>>v;
add(u,v);
degree[v]++;
}
cin>>s>>t;
for(int i = 1;i <= n;++i)
{
if(!degree[i]) LCA(i);
}
}
return 0;
}
参考代码: