Fork me on 
Catalogue

我自问酒不问仙,半世逍遥半世癫,我自问心不问佛,半世情愁半世痴。 ​​​​

汉孤臣の倍增LCA模板

例题 (模板题):https://vjudge.net/problem/51Nod-2599

代码:

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <deque>
#include <queue>
using namespace std;
const int maxn=100000+50;
int n,deep[maxn],h[maxn],f[maxn][20],q,cnt;
struct node
{
    int b,next;
}table[maxn];
struct nodee
{
    vector<int> fa,child;
}tree[maxn];
void add(int x,int y)     //先储存边 (例题为例,先储存无向关系) 
{
    table[++cnt].b=y;
    table[cnt].next=h[x];
    h[x]=cnt;
}
void dfs(int x,int deepx)          //将不确定的无向边变成父子关系 ,并完成倍增的初始化 
{
    deep[x]=deepx;
    int t1;
    for (int i=h[x]; i; i=table[i].next)
        if (!deep[table[i].b])
        {
            t1=table[i].b;
            tree[x].child.push_back(t1);
            tree[t1].fa.push_back(t1); f[t1][0]=x;
            for (int i=1; i<=10; i++)//别忘调节大小 
                f[t1][i]=f[f[t1][i-1]][i-1];
            dfs(t1,deepx+1);
        }
}
int query(int x,int y)
{
    if (deep[x]<deep[y]) swap(x,y);
    for (int i=10; i>=0; i--)
        if (deep[f[x][i]]>=deep[y])
            x=f[x][i];
    for (int i=10; i>=0; i--)
        if (f[x][i]!=f[y][i])
            x=f[x][i],y=f[y][i];
    if (x!=y) return f[x][0];
    else return x;
}
int main()
{
    memset(deep,0,sizeof(deep)); cnt=0;
    memset(f,0,sizeof(f));
    memset(h,0,sizeof(h));
    scanf("%d",&n);
    for (int i=0; i<=n; i++)
    {
        tree[i].child.clear(); tree[i].fa.clear();
    }
    for (int i=1,q1,q2; i<n; ++i)
    {
        scanf("%d%d",&q1,&q2);
        add(q1,q2); add(q2,q1);
    }
    dfs(1,1);
    scanf("%d",&q);
    for (int i=1,q1,q2; i<=q; ++i) 
    {
        scanf("%d%d",&q1,&q2);
        printf("%d\n",query(q1,q2));
    }
    return 0;
}

树的基础内容

 

posted @ 2020-10-21 21:27  汉孤臣  阅读(85)  评论(0)    收藏  举报
Live2D