Latest Common Ancestor

倍增求LCA

时间复杂度O(nlogn)

模板

#include <cstdio>
#include <algorithm>
#include <cstring>
#include<queue>
using namespace std;

const int maxn = 10007;
const int DEG = 20;

int head[maxn*2],nxt[maxn*2],to[maxn*2],tot;

void init()
{
    tot=0;
    memset(head,0,sizeof(head));
    memset(nxt,0,sizeof(nxt));
}

void add(int u,int v)
{
    ++tot;
    to[tot]=v;
    nxt[tot]=head[u];
    head[u]=tot;
}

int fa[maxn][DEG];  //fa[i][j]表示结点i的第2^j个祖先
int deg[maxn];      //深度数组

void bfs(int root)
{
    queue<int>que;
    deg[root]=0;
    fa[root][0]=root;
    que.push(root);
    while(!que.empty())
    {
        int tmp=que.front();
        que.pop();
        for(int i=1;i<DEG;i++)
            fa[tmp][i]=fa[fa[tmp][i-1]][i-1];
        for(int i=head[tmp];i;i=nxt[i])
        {
            int v=to[i];
            if(v==fa[tmp][0]) continue;
            deg[v]=deg[tmp]+1;
            fa[v][0]=tmp;
            que.push(v);
        }
    }
}

int LCA(int u,int v)
{
    if(deg[u]>deg[v]) swap(u,v);
    int hu=deg[u],hv=deg[v];
    int tu=u,tv=v;
    for(int det=hv-hu,i=0;det;det>>=1,i++)
        if(det&1) tv=fa[tv][i];
    if(tu==tv) return tu;
    for(int i=DEG-1;i>=0;i--)
    {
        if(fa[tu][i]==fa[tv][i])
            continue;
        tu=fa[tu][i];
        tv=fa[tv][i];
    }
    return fa[tu][0];
}

bool flag[maxn];
int main()
{
    int tt,n,u,v;
    scanf("%d",&tt);
    while(tt--)
    {
        init();
        scanf("%d",&n);
        memset(flag,false,sizeof(flag));
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            add(u,v),add(v,u);
            flag[v]=true;  // !!!!
        }
        int root;
        for(int i=1;i<=n;i++)
        {
            if(!flag[i])
            {
                root=i;
                break;
            }
        }
        bfs(root);
        scanf("%d%d",&u,&v);
        printf("%d\n",LCA(u,v));
    }
    return 0;
}

POJ1330

分析

模板题


 

SPOJ COT

分析

根据dfs序建主席树,lca求最近公共祖先结点后,正常的按照主席树查询第k大即可


 

posted @ 2018-05-15 16:28  Deadlined  阅读(144)  评论(0编辑  收藏  举报