POJ 1330 Nearest Common Ancestors Tarjan求LCA

来源:互联网 发布:淘宝娜拉nala有假货吗 编辑:程序博客网 时间:2024/04/29 23:29

这道题就是传说中的LCA了,从网上找了一个模板,用数组模拟的树

大概的原理, 大概就是:首先,把每个节点的祖先标记为自己,如果在一个子树内没有解决查询的LCA问题,那么该子树的所有节点的都将直接或间接的指向该子树的直接父亲,也就是子树内的所有节点的祖先都是该子树的父亲,然后就可以在该父亲的其他儿子中寻找。

#include <iostream>#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <cstring>#include <cmath>#include <ctime>#define INF 1000000000using namespace std;const int MAXN = 10005;struct Tree{    int head[MAXN];    int next[MAXN];    int node[MAXN];    int pos;    Tree()    {        clear();    }    void clear()    {        memset(head, -1, sizeof(head));        pos = 0;    }    void add(int s, int e)    {        node[pos] = e;        next[pos] = head[s];        head[s] = pos++;    }}tree;bool v[MAXN];int in[MAXN];int father[MAXN];int x, y;int find(int x){    if(father[x] == x) return x;    int t = find(father[x]);    father[x] = t;    return t;}void LCA(int u){    father[u] = u;//当访问到一个点的时候,先将其自己形成一个集合    for(int i = tree.head[u]; i != -1; i = tree.next[i])    {        LCA(tree.node[i]);  //依次对子节点进行访问并处理        father[tree.node[i]] = u;  //在处理完后,将子节点的集合链接到父节点    }    v[u] = 1; //标记访问过该点    if(u == x && v[y])  //如果当前点是查询中两点中的一点并且另外一点已经访问过,那么另一点的祖先即为公共祖先    {        printf("%d\n", find(y));        return;    }    else if(u == y && v[x])    {        printf("%d\n", find(x));        return;    }}int main(){    int T;    scanf("%d", &T);    while(T--)    {        memset(v, 0, sizeof(v));        memset(in, 0, sizeof(in));        tree.clear();        int n, s, e;        scanf("%d", &n);        for(int i = 1; i < n; i++)        {            scanf("%d%d", &s, &e);            tree.add(s, e);            in[e]++;        }        scanf("%d%d", &x, &y);        for(int i = 1; i <= n; i++)        {            if(in[i] == 0)            {                 LCA(i);                 break;            }        }    }    return 0;}


原创粉丝点击