Training for LCA

POJ1330

分析

lca模板题,数组开小了找了一个多小时

#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
const int maxn = 1e5+7;

int d[maxn],fa[maxn][32];
vector<int>g[maxn];
bool vv[maxn];
bool vis[maxn];
int n,t,u,v;

void init()
{
    //d[1]=1;
    for(int i=1;i<=n;i++) vis[i]=false,vv[i]=false,g[i].clear();
}

void dfs(int u)  // dfs预处理出每个节点的深度
{
    vis[u]=1;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!vis[v])
        {
            d[v]=d[u]+1;
           // cout<<v<<' '<<d[v]<<endl;
            dfs(v);
        }
    }
}

void bz()
{
   // cout<<fa[16][0]<<endl;
    for(int j=1;j<=30;j++)
        for(int i=1;i<=n;i++)
        {
                fa[i][j]=fa[fa[i][j-1]][j-1];

        }
}

int LCA(int u,int v)
{
    if(d[u]<d[v])
        swap(u,v);
    int dc=d[u]-d[v];
    for(int i=0;i<30;i++){
        if((1<<i)&dc)
            u=fa[u][i];
    }
    if(u==v) return u;
    for(int i=30;i>=0;i--)
    {
        if(fa[u][i] != fa[v][i])
        {
            u=fa[u][i];
            v=fa[v][i];
        }
    }
    u=fa[u][0];
    return u;
}

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d", &n);
        init();
        for(int i=1;i<=n-1;i++)
        {
            scanf("%d%d", &u, &v);
            fa[v][0]=u;
            vv[v]=1;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        int st;
        for(int i=1;i<=n;i++)
            if(!vv[i])
              st=i;
        fa[st][0]=st;
        d[st]=0;
        dfs(st);
        bz();
        scanf("%d%d", &u, &v);
        printf("%d\n", LCA(u,v));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Deadline/p/9163048.html
lca