您的位置:首页 > 其它

POJ 1330 LCA入门题(Tarjan)

2013-10-20 11:50 543 查看
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
#define N 100010
#define bug(a) cout<<a<<"******"<<endl;

int ok;
int fa
,node
,vis
,anc
,ans;
struct node
{
int to;
int next;
}edge[N<<2];

int head
,cnt;
int que[2];

void init()
{
memset(head,-1,sizeof(head));
memset(node,0,sizeof(node));
memset(vis,0,sizeof(vis));
cnt = 0;
}

void add( int u , int v )
{
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}

int find(int x)
{
if(fa[x] != x)
return fa[x] = find(fa[x]);
return x;
}

void uni(int u,int v)
{
int x = find(u);
int y = find(v);
if( x != y )
fa[x] = y;
}

void LCA(int u)
{
int i,j,v;
vis[u] = 1;
for ( i = head[u] ; i != -1 ; i = edge[i].next )
{
v = edge[i].to;
if(vis[v])
continue;
LCA(v);
uni(u,v);
anc[find(v)] = u;
}
if( u == que[0] && vis[que[1]] )
{
ans = anc[find(que[1])];
return ;
}
if( u == que[1] && vis[que[0]])
{
ans = anc[find(que[0])];
return ;
}
}

int main()
{
int i,j,T,n,u,v;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
for( i = 0 ; i <= n ; i ++ )
fa[i] = i ;
for ( i = 0 ; i < n - 1 ; i ++ )
{
scanf("%d%d",&u,&v);
add(u,v);
node[v] ++;
}
scanf("%d%d",&que[0],&que[1]);
for ( i = 1 ; i <= n ; i ++ )
{
if(!node[i])
{
LCA(i);
printf("%d\n",ans);
break;
}
}
}
return 0 ;
}


题目大意:

输入T组测试数据

输入N

接下来N-1行代表了一条边

输入A,B,其中A为B的父节点

第N行为询问,问该两点的最近公共祖先

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LCA