离线tarjan算法求LCA

#include <cmath>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <map>
#include <cctype>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cout<<"["<<"x = "<<(x)<<"] "
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e6 + 5;
const int mod = 998244353;
/*
tarjan离线求LCA
*/

struct node {
    int v, nxt;
} e[maxn];
int  tot, head[maxn];
void add_edge(int u, int v) {//存边
    e[tot].v = v;
    e[tot].nxt = head[u];
    head[u] = tot++;

    e[tot].v = u;
    e[tot].nxt = head[v];
    head[v] = tot++;
}
struct qnode {//存查询
    int id, v, nxt;
} qe[maxn];
int  qtot, qhead[maxn];
void add_q(int u, int v, int id) {//双向的
    qe[qtot].v = v;
    qe[qtot].id = id;
    qe[qtot].nxt = qhead[u];
    qhead[u] = qtot++;

    qe[qtot].v = u;
    qe[qtot].id = id;
    qe[qtot].nxt = qhead[v];
    qhead[v] = qtot++;
}
int f[maxn];
int getf(int x) {//并查集
    return f[x] == x ? x : f[x] = getf(f[x]);
}
int n, m, s, ans[maxn], vis[maxn];//ans存答案
void init() {//初始化
    CLR(head, -1);
    CLR(qhead, -1);
    CLR(vis, 0);
    tot = qtot = 0;
    for(int i = 1; i <= n; i++) f[i] = i;
}
void dfs(int u) {//递归查询答案
    vis[u] = 1;
    for(int i = head[u]; ~i; i = e[i].nxt) {
        int v = e[i].v;
        if(!vis[v]) {
            dfs(v);
            int t1 = getf(u);
            int t2 = getf(v);
            if(t1 != t2) {//合并
                f[t2] = t1;
            }
        }
    }
    for(int i = qhead[u]; ~i; i = qe[i].nxt) {
        int v = qe[i].v;
        if(vis[v]) {//如果当前查询的另一个节点已经被访问过,就能确定答案了
            ans[qe[i].id] = getf(v);
        }
    }
}
int main() {
    scanf("%d%d%d", &n, &m, &s);
    init();
    for(int i = 1; i <= n - 1; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        add_edge(u, v);
    }
    for(int i = 1; i <= m; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        add_q(u, v, i);
    }
    dfs(s);
    for(int i = 1; i <= m; i++) printf("%d\n", ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/81591271