您的位置:首页 > 其它

【poj】lca模板题 poj1330

2015-07-30 13:32 483 查看
附题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11136
Nearest Common Ancestors

Time Limit: 1000MSMemory Limit: 10000KB64bit IO Format: %I64d & %I64u
Submit Status

Description

A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct edge{
int u,v,next;
}e[10000 + 10];
int head[10000 + 10],k = 1;
int deep[10000 + 5];
int vis[10000 + 5];
int p[10000][20 + 5];//p[i][j]表示第i点的第2^j个祖先
int T;
int n;
void adde(int u,int v)
{
e[k].u = u;
e[k].v = v;
e[k].next = head[u];
head[u] = k++;
}
void dfs(int u)
{
for(int i = head[u]; i ; i = e[i].next)
{
if(!deep[e[i].v])
{
deep[e[i].v] = deep[u] + 1;
p[e[i].v][0] = u;
dfs(e[i].v);
}
}
}
void init()
{
int i, j;
for(j = 1; (1 << j) <= n; j++)
{
for(i = 1; i <= n; i++)
{
//if(p[i][j - 1] != -1)
p[i][j] = p[p[i][j - 1]][j - 1];//i的第2^j-1的祖先的第2^j-1的祖先就是i的第2^j个祖先,有点绕,可画图看
}
}
}
int lca(int a,int b)
{
int i, j;
if(deep[a] < deep[b])swap(a,b);
for(i = 0; (1 << i) <= n; i++);
i--;//找出最多跳的次数
for(j = i; j >= 0; j--)
if(deep[a] - (1 << j) >= deep[b])
a = p[a][j];//跳到与b同一深度
if(a == b)return a;//此情况是a,b同点
for(j = i; j >= 0; j--)
{
if(p[a][j] != -1 && p[a][j] != p[b][j])//a,b的最远的不相等的祖先的父亲就是求得lca
{
a = p[a][j];
b = p[b][j];//不断向上跳
}
}
return p[a][0];//最后a的父亲便是lca
}
int main()
{
scanf("%d",&T);
while(T--)
{
int root;
memset(p,0,sizeof(p));
memset(deep,0,sizeof(deep));
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
//memset(e,0,sizeof(e));
k = 1;
scanf("%d",&n);
for(int i = 1; i < n; i++)
{
int a,b;
scanf("%d%d",&a,&b);
p[b][0] = a;
adde(a,b);
if(p[a][0] == 0)
root = a;
}
deep[root] = 1;
dfs(root);
init();
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}

return 0;
}


View Code
最后想说的是,为什么会超时,似乎有点问题。。到时等理解更深后在来优化吧,代码没问题。就当做模板吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: