1 题意,求LCA——Least Common Ancestors,最近公共祖先。
2 分析
代码二,先dfs将各个节点的层数标记上。
代码一,标记一下数组。
3
代码一,16ms
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn=10010;
int parent[maxn];
int vis[maxn];
int Find(int a,int b){
//分开便利OR一步一ch
while(!vis[a]){
vis[a]=1;
if(-1!=parent[a])
a=parent[a];
}
while(!vis[b]){
b=parent[b];
}
return b;
}
int main()
{
int kk;
scanf("%d",&kk);
while(kk--){
int n,a,b;
memset(parent,-1,sizeof(parent));
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&a,&b);
parent[b]=a;
}
scanf("%d%d",&a,&b);
int res=Find(a,b);
cout<<res<<endl;
}
}
代码二,60ms
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=10010;
int parent[maxn];
vector <int> son[maxn];
int r[maxn];//????????
void DLR(int root,int step){
r[root]=step;//
for(int i=0;i<son[root].size();i++)
DLR(son[root][i],step+1);
}
int Find(int a,int b){
while(a!=b){
if(r[a]>r[b]&&parent[a]!=-1)
a=parent[a];
else if(r[a]<=r[b]&&parent[b]!=-1)
b=parent[b];
}
return a;
}
int main()
{
int kk;
scanf("%d",&kk);
while(kk--){
int n,a,b;
for(int i=0;i<maxn;i++){
son[i].clear();
r[i]=-1;
parent[i]=-1;
}
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&a,&b);
son[a].push_back(b);
parent[b]=a;
}
int root=1;
for(root=1;parent[root]!=-1;root++);//?????????????????1,2,...n
DLR(root,0);//DLR??????data(?) left right;0???
scanf("%d%d",&a,&b);
int res=Find(a,b);
cout<<res<<endl;
}
}