poj 1330 【最近公共祖先问题+fa[]数组+ 节点层次搜索标记】

题目地址:http://poj.org/problem?id=1330

Sample Input

2
16
1 14
8 5
10 16
5 9
4 6
8 4
4 10
1 13
6 15
10 11
6 7
10 2
16 3
8 1
16 12
16 7
5
2 3
3 4
3 1
1 5
3 5

Sample Output

4
3

n个节点、n-1条边,生成的一定是一棵树。找到最后的那组x y的最近的公共祖先。并查集思想实现的LCA

节点编号为:1-->n

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#define N 10000+10

using namespace std;

vector<int>a[N];
int fa[N];//记录每个节点的父亲节点
int r[N];//记录每个节点所在的层次

void dfs(int u, int dep)
{       //通过先根遍历计算每个节点的层次
    r[u]=dep;
    vector<int>::iterator it;
    for(it=a[u].begin(); it!=a[u].end(); it++)
    {
        dfs(*it, dep+1);
    }
}

int main()
{
    int tg; scanf("%d", &tg);
    int i, j, k;
    int n, u, v;

    while(tg--)
    {
        scanf("%d", &n);
        for(i=1; i<=n; i++){
            a[i].clear();
            fa[i]=i;//自己是自己的父亲节点
        }

        for(i=0; i<n-1; i++){
            scanf("%d %d", &u, &v);
            a[u].push_back(v);
            fa[v]=u; //u是v的父亲
        }
        for(i=1; i<=n; i++)
            if(fa[i]==i) break;//找到根节点
        dfs(i, 0); //计算每个节点的层次
        int x, y;//寻找x y的最近公共祖先
        scanf("%d %d", &x, &y);
        while(x!=y)
        {
            if(r[x]>r[y]) x=fa[x];//说明x的辈分比y小 将x的父亲搬过来
            else y=fa[y];
        }
        printf("%d
", x);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yspworld/p/4722409.html