HDU 2586 How far away ?(LCA裸题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586

HDU 2586 How far away ?(LCA裸题)
#include<bits/stdc++.h>
#define lson rt << 1, l, m
#define rson rt << 1 | 1, m + 1, r
using namespace std;
typedef long long ll;
static const ll inf = (1 << 32);
static const int INF = 0x3f3f3f3f;
static const int MAX_N = 4e4 + 5;
static const int N = 5005;
struct Edge{
    int to, dis;
    Edge(int _to, int _dis){to = _to; dis = _dis;}
};
int n;
vector<Edge>edge[MAX_N];
int fa[MAX_N], dep[MAX_N], dis[MAX_N];
int par[MAX_N][30];
void dfs(int u, int pre, int depth){
    fa[u] = pre;
    dep[u] = depth;
    int le = edge[u].size();
    for(int i = 0; i < le; ++i){
        int v = edge[u][i].to;
        if(v == pre) continue;
        dis[v] = dis[u] + edge[u][i].dis;
        dfs(v, u, depth + 1);
    }
}
void init_LCA(){
    for(int j = 0; (1 << j) <= n; ++j){
        for(int i = 1; i <= n; ++i){
            par[i][j] = -1;
        }
    }
    for(int i = 1; i <= n; ++i) par[i][0] = fa[i];
    for(int j = 1; (1 << j) <= n; ++j){
        for(int i = 1; i <= n; ++i){
            if(par[i][j - 1] != -1) par[i][j] = par[par[i][j - 1]][j - 1];
        }
    }
}
int LCA(int x, int y){
    if(dep[x] < dep[y]) swap(x, y);
    int lg;
    for(lg = 0; (1 << lg) <= dep[x]; ++lg);
    --lg;
    for(int i = lg; i >= 0; --i){
        if(dep[x] - (1 << i) >= dep[y]){
            x = par[x][i];
        }
    }
    if(x == y) return x;
    for(int i = lg; i >= 0; --i){
        if(par[x][i] != -1 && par[x][i] != par[y][i]){
            x = par[x][i], y = par[y][i];
        }
    }
    return fa[x];
}
void addEdge(int u, int v, int w){
    edge[u].push_back(Edge(v, w));
}
int main(){
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    int t, m;
    scanf("%d", &t);
    while(t--){
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i) edge[i].clear();
        for(int i = 1; i < n; ++i){
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            addEdge(u, v, w);
            addEdge(v, u, w);
        }
        dis[1] = 0;
        dfs(1, -1, 0);
        init_LCA();
        while(m--){
            int u, v;
            scanf("%d%d", &u, &v);
            printf("%d\n", dis[u] + dis[v] - 2 * dis[LCA(u, v)]);
        }
    }
    return 0;
}
View Code

 

上一篇:并查集的实现


下一篇:专业现场媒体编辑工具QLab Pro for Mac