您的位置:首页 > 其它

poj 1330 Nearest Common Ancestors

2012-05-29 21:25 477 查看
http://poj.org/problem?id=1330

最近公共父结点

离线算法 LCA

用并查集 和 dfs

每搜到一个点 先让其父结点等于自己

继续往下搜 这时如果询问已搜过的点 则两点之间的最近公共父结点就是 已搜过的点的最上父结点

若没搜过 就继续深搜

所用相连的点都搜完后 让此点的父结点为上一层结点

#include<iostream>
#include<cstring>

using namespace std;

const int N=10005;
struct node
{
struct tt *next;
}mem
;
struct tt
{
struct tt *next;
int j;
};
void build(int i,int j)
{
struct tt *t=new tt;
t->j=j;
t->next=mem[i].next;
mem[i].next=t;
}
bool had
;
bool visited
;
int f
;
int l,r;
int ans;
int findf(int x)
{
if(x!=f[x])
f[x]=findf(f[x]);
return f[x];
}
void searchans(int x)
{
if(x==l)
{
if(visited[r]==true)
{
ans=findf(r);
}
}
else
{
if(visited[l]==true)
{
ans=findf(l);
}
}
//cout<<x<<" "<<ans<<endl;
}
void dfs(int pre,int x)
{

visited[x]=true;
f[x]=x;
if(x==l||x==r)
searchans(x);
struct tt *t=mem[x].next;
while(t!=NULL)
{
if(visited[t->j]==false)
dfs(x,t->j);
t=t->next;
}
f[x]=pre;
}
void Lca(int n)
{
memset(visited,false,sizeof(visited));
for(int i=1;i<=n;++i)
{
if(had[i]==false)
{
dfs(i,i);
break;
}
}
}
void Clear(int n)
{
for(int i=1;i<=n;++i)
mem[i].next=NULL;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
memset(had,false,sizeof(had));
for(int w=1;w<n;++w)
{
int i,j;
cin>>i>>j;
had[j]=true;
build(i,j);
}
cin>>l>>r;
Lca(n);
cout<<ans<<endl;
Clear(n);
}

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