Poj1330 LCA模板题

题目链接


http://poj.org/problem?id=1330
 本体题意就是给定一颗树,求a, b两点的最近公共父节点,直接用来学习模板,模板是网上大神的,我做了一点注释,容易理解。(我喜欢离线的处理)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#define rep(i, s, t) for(int i = s;i <= t;i++)
#define rap(i, s, t) for(int i = s;i >= t;i--)
using namespace std;
const int M = 10009;
vector<int>tree[M];
vector<int>query[M];
int n;
bool vis[M];
int in[M];
int f[M];
int root;
int ancestor[M];
int findd(int x)//递归找并查集标记
{
    return x == f[x] ? f[x] : f[x] = findd(f[x]);
}
void uni(int x, int y)//合并并查集
{
    x = findd(x);
    y = findd(y);
    if(x != y)
        f[x] = y;
}
void init()//初始化
{
    rep(i, 0, n){
        vis[i] = false;
        tree[i].clear();
        query[i].clear();
        in[i] = 0;
        f[i] = i;
    }
}
void input_tree()//建图,找树的根节点
{
    rep(i, 0, n - 2){
        int a, b;
        scanf("%d%d", &a, &b);
        tree[a].push_back(b);
        in[b]++;//标记入度
    }
    rep(i, 1, n)//根节点的入度为0
        if(in[i] == 0)
            root = i;
}
void input_query()//离线读入询问
{
    rep(i, 0, 0){
        int a, b;
        scanf("%d%d", &a, &b);
        query[a].push_back(b);
        query[b].push_back(a);
    }
}
void tarjan(int x)
{
    rep(i, 0, (int)tree[x].size() - 1){
        int v = tree[x][i];
        tarjan(v);//先处理子节点
        uni(x, v);//合并子节点和父节点并查集
        ancestor[findd(x)] = x;//改并查集的所有节点的父节点就是x
    }
    vis[x] =true;
    rep(i, 0, (int)query[x].size() - 1)//由于更新父节点是从下向上更新的所以最先找到的公共父节点就是最近的父节点。
    {
        int v = query[x][i];
        if(vis[v])
            printf("%d\n", ancestor[findd(v)]);
    }
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        init();
        input_tree();
        input_query();
        tarjan(root);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值