【算法】【树】最近公共祖先LCA——Tarjan算法

来源:互联网 发布:怎么上架淘宝宝贝 编辑:程序博客网 时间:2024/05/22 10:59
class LCA_problem {public:    const static int N = 10000 + 10;    int parent[N];    int ancester[N];    vector<int> tree[N];    vector<int> qes[N];    bool isroot[N];    bool visited[N];    int n;    void init(int n) {        for (int i = 1; i <= n; i++) {            parent[i] = i;            isroot[i] = true;            ancester[i] = 0;            visited[i] = false;            qes[i].clear();            tree[i].clear();        }    }    int find(int u) {        if (u != parent[u]) {parent[u] = find(parent[u]); return parent[u];}        return u;    }    int union_(int x, int y) {        int p1 = find(x);        int p2 = find(y);        if (p1==p2) return 0;        parent[p1] = p2;        return 1;    }    void lca(int u) {   //模拟深度遍历,在遍历的过程中,回答查询问题;        ancester[u] = u;        int size = tree[u].size();        //printf("# %d %d\n", u, size);        for (int i = 0; i < size; i++) {                        lca(tree[u][i]);            union_(u, tree[u][i]);            ancester[find(u)] = u;                    }        visited[u] = true;        size = qes[u].size();        for (int i = 0;i < size; i++) {            if (visited[qes[u][i]]) {                printf("%d\n", ancester[find(qes[u][i])]);                return;            }        }    }    void solve() {        int test_num, start, end;        scanf("%d", &test_num);        for (int t = 0; t < test_num; t++) {            scanf("%d", &n);            init(n);            for (int i = 0;i < n-1; i++) {                scanf("%d%d", &start, &end);                tree[start].push_back(end);                isroot[end] = false;            }            scanf("%d%d", &start, &end);            qes[start].push_back(end);            qes[end].push_back(start);            for (int i = 1; i <= n; i++) {                if (isroot[i]) { lca(i); break; }            }        }    }};

0 0
原创粉丝点击