HDU 2586 How far away ?——lca

来源:互联网 发布:下载语音助手软件 编辑:程序博客网 时间:2024/06/10 16:27

假设dis【i】为i到根节点的距离,那么u和v之间的距离为dis【u】 + dis【v】 - 2 * dis【lca(u,v)】

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>using namespace std;typedef pair<int, int> P;const int maxn = 4 * 1e4 + 10;int n, m;vector<P> G[maxn];vector<P> link[maxn];int ans[500];int par[maxn];bool vis[maxn];struct Data {    int u, v;}data[500];int dis[maxn];//节点i到根节点1的距离int query(int x) {    return par[x] == x ? x : par[x] = query(par[x]);}void merge(int x, int y) {    x = query(x); y = query(y);    if (x != y) par[y] = x;}void lca(int u) {    vis[u] = true;    for (unsigned int i = 0; i < G[u].size(); i++) {        int v = G[u][i].first, d = G[u][i].second;        if (!vis[v]) {            dis[v] = dis[u] + d;            lca(v);            merge(u, v);        }    }    for (unsigned int i = 0; i < link[u].size(); i++) {        int v = link[u][i].first, id = link[u][i].second;        if (vis[v]) ans[id] = query(v);    }}void solve() {    for (int i = 1; i <= m; i++) {        int u = data[i].u, v = data[i].v;        ans[i] = dis[u] + dis[v] - 2 * dis[ans[i]];    }}int main() {    int T; scanf("%d", &T);    for (int kase = 1; kase <= T; kase++) {        scanf("%d %d", &n, &m);        for (int i = 0; i <= n; i++) G[i].clear(), link[i].clear(), par[i] = i, vis[i] = false, dis[i] = 0;        for (int i = 1; i <= n - 1; i++) {            int u, v, dis; scanf("%d %d %d", &u, &v, &dis);            G[u].push_back(make_pair(v, dis));            G[v].push_back(make_pair(u, dis));        }        for (int i = 1; i <= m; i++) {            int u, v; scanf("%d %d", &u, &v);            data[i].u = u, data[i].v = v;            link[u].push_back(make_pair(v, i));            link[v].push_back(make_pair(u, i));        }        lca(1);        solve();        for (int i = 1; i <= m; i++) {            printf("%d\n", ans[i]);        }    }    return 0;}


原创粉丝点击