并查集解树的最近公共祖先问题

来源:互联网 发布:unity3d模型资源百度云 编辑:程序博客网 时间:2024/06/05 20:51

题目链接:http://poj.org/problem?id=1330

最近公共祖先(LCA)

题意:求树上亮点的最近公共祖先,就是求包含这两个点的最小的子树的根节点。

离线算法(Tarjan):

就是预先储存所有询问,然后深搜便利所有点,后序遍历找到每个询问中的点,对于每个询都是在两个点都找到的那一刻得到最近公共祖先,后序遍历中不断把点加入并查集中,已加入的最上面的点就是当前的根节点。

解题代码:

#include<iostream>#include<cstdio>using namespace std;int a[10005];int find(int x,int y){    int m1=x,m2,flag=0;    while(true)    {        m2=y;        while(true)        {            if(m1==m2)            {                flag=m1;                break;            }            if(a[m2]==m2)                break;            m2=a[m2];        }        if(flag!=0)            break;        if(a[m1]==m1)            break;        m1=a[m1];    }    return flag;}int main(){    int T,n,node1,node2,ans;    scanf("%d",&T);    for(int i=0;i<T;i++)    {        scanf("%d",&n);        for(int j=0;j<n;j++)            a[j+1]=j+1;        for(int j=0;j<n-1;j++)        {            scanf("%d%d",&node1,&node2);            a[node2]=node1;        }        scanf("%d%d",&node1,&node2);        ans=find(node2,node1);        printf("%d\n",ans);    }    return 0;}

本题的收获:学会了并查集的使用,通过并查集能够根据父子节点间的关系很快的建树。

解本题所查看过的资料:http://blog.csdn.net/dellaserss/article/details/7724401/   (并查集详解)


0 0
原创粉丝点击