您的位置:首页 > 其它

POJ 1330 (LCA)

2014-08-23 16:49 211 查看
http://poj.org/problem?id=1330

题意:给出一个图,求两个点的最近公共祖先。

sl :水题,贴个模板试试代码。本来是再敲HDU4757的中间发现要用LCA, 操蛋只好用这个题目试试自己写的对不对。 下面是个倍增的写法,挺实用的。

好了,继续。。。

1 #include <cstdio>
2 #include <cstring>
3 #include <vector>
4 #include <algorithm>
5 #include <map>
6 #include <cmath>
7 using namespace std;
8 const int MAX = 1e4+10;
9 vector<int> G[MAX];
int is_root[MAX];
int parent[15][MAX],dep[MAX];
int n,m;
void add_edge(int from,int to) {
G[from].push_back(to);
G[to].push_back(from);
}
void dfs(int u,int pre,int d) {
dep[u]=d; parent[0][u]=pre;
for(int i=0;i<G[u].size();i++) {
int v=G[u][i];
if(v!=pre) dfs(v,u,d+1);
}
return ;
}
void init() {
int x;
for(int i=1;i<=n;i++) {
if(is_root[i]) {
x=i; break;
}
}

dfs(x,-1,0);
for(int k=0;k<14;k++) {
for(int v=1;v<=n;v++) {
if(parent[k][v]<0) parent[k+1][v]=-1;
else parent[k+1][v]=parent[k][parent[k][v]];
}
}
}
int LCA(int u,int v) {
if(dep[u]>dep[v]) swap(u,v);
for(int k=0;k<15;k++) {
if((dep[v]-dep[u])>>k&1) v=parent[k][v];
}
if(u==v) return u;
for(int k=14;k>=0;k--) {
if(parent[k][u]!=parent[k][v]) {
u=parent[k][u]; v=parent[k][v];
}
}
return parent[0][u];
}
void CLEAR() {
for(int i=0;i<MAX;i++) G[i].clear();
}
int main() {
int cas; int a,b;
scanf("%d",&cas);
while(cas--) {
CLEAR();
scanf("%d",&n);
memset(is_root,true,sizeof(is_root));
for(int i=1;i<=n-1;i++) {
scanf("%d %d",&a,&b);
add_edge(a,b);
is_root[b]=false;
}
init();
scanf("%d %d",&a,&b);
int ans=LCA(a,b);
printf("%d\n",ans);
}
return 0;
}SB CODE
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: