[LCA] tarjan算法 模版

LCA算法:

LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点。也就是说,在两个点通往根的道路上,肯定会有公共的节点,我们就是要求找到公共的节点中,深度尽量深的点。还可以表示成另一种说法,就是如果把树看成是一个图,这找到这两个点中的最短距离。

tarjan算法是离线算法,复杂度为O(n+Q),使用了并查集+dfs的操作。中间的那个并查集操作的作用,只是将已经查找过的节点捆成一个集合然后再指向一个公共的祖先。另外,如果要查询LCA(a,b),必须把(a,b)和(b,a)都加入邻接表。

如poj1330为例

#include 
#include 
#include 
#include 

using namespace std;

#define MAXN 10001

int n,fa[MAXN];
int rank[MAXN];
int indegree[MAXN];
int vis[MAXN];
vector hash[MAXN],Qes[MAXN];
int ances[MAXN];//祖先


void init(int n)
{
    for(int i=0;i<=n;i++)
    {
        fa[i]=i;
        rank[i]=0;
        indegree[i]=0;
        vis[i]=0;
        ances[i]=0;
        hash[i].clear();
        Qes[i].clear();
    }
}

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

void unio(int x,int y)
{
    int fx=find(x),fy=find(y);
    if(fx==fy) return ;
    if(rank[fy]


 

你可能感兴趣的:(LCA与RMQ)