#include #include #include using namespace std;

const int MAX_N = 100005; const int LOG = 20;

vector adj[MAX_N]; int depth[MAX_N]; int up[LOG][MAX_N];

void dfs(int u, int parent) { up[0][u] = parent; for (int v : adj[u]) { if (v != parent) { depth[v] = depth[u] + 1; dfs(v, u); } } }

int lca(int u, int v) { if (depth[u] < depth[v]) swap(u, v);

// 将较深的节点提升到较浅节点的深度
for (int k = LOG-1; k >= 0; --k) {
    if (depth[u] - (1 << k) >= depth[v]) {
        u = up[k][u];
    }
}

if (u == v) return u;

// 同时向上跳跃寻找LCA
for (int k = LOG-1; k >= 0; --k) {
    if (up[k][u] != up[k][v]) {
        u = up[k][u];
        v = up[k][v];
    }
}
return up[0][u];

}

int main() { int n; cin >> n;

// 构建邻接表
for (int i = 0; i < n-1; ++i) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// 初始化根节点(假设根为1)
depth[1] = 0;
dfs(1, 1);

// 预处理倍增表
for (int k = 1; k < LOG; ++k) {
    for (int u = 1; u <= n; ++u) {
        up[k][u] = up[k-1][up[k-1][u]];
    }
}

// 处理查询
int Q;
cin >> Q;
while (Q--) {
    int u, v;
    cin >> u >> v;
    int ancestor = lca(u, v);
    int distance = depth[u] + depth[v] - 2 * depth[ancestor];
    cout << distance << endl;
}

return 0;

}

1 条评论

  • #include #include #include using namespace std;

    const int MAX_N = 100005; const int LOG = 20;

    vector adj[MAX_N]; int depth[MAX_N]; int up[LOG][MAX_N];

    void dfs(int u, int parent) { up[0][u] = parent; for (int v : adj[u]) { if (v != parent) { depth[v] = depth[u] + 1; dfs(v, u); } } }

    int lca(int u, int v) { if (depth[u] < depth[v]) swap(u, v);

    // 将较深的节点提升到较浅节点的深度
    for (int k = LOG-1; k >= 0; --k) {
        if (depth[u] - (1 << k) >= depth[v]) {
            u = up[k][u];
        }
    }
    
    if (u == v) return u;
    
    // 同时向上跳跃寻找LCA
    for (int k = LOG-1; k >= 0; --k) {
        if (up[k][u] != up[k][v]) {
            u = up[k][u];
            v = up[k][v];
        }
    }
    return up[0][u];
    

    }

    int main() { int n; cin >> n;

    // 构建邻接表
    for (int i = 0; i < n-1; ++i) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    
    // 初始化根节点(假设根为1)
    depth[1] = 0;
    dfs(1, 1);
    
    // 预处理倍增表
    for (int k = 1; k < LOG; ++k) {
        for (int u = 1; u <= n; ++u) {
            up[k][u] = up[k-1][up[k-1][u]];
        }
    }
    
    // 处理查询
    int Q;
    cin >> Q;
    while (Q--) {
        int u, v;
        cin >> u >> v;
        int ancestor = lca(u, v);
        int distance = depth[u] + depth[v] - 2 * depth[ancestor];
        cout << distance << endl;
    }
    
    return 0;
    

    }

    • 1

    信息

    ID
    1368
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    (无)
    递交数
    183
    已通过
    32
    上传者