bzoj 1832 LCA

思路:好裸的LCA呀。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg
using namespace std;

const int N = 5e5 + 7;
const int M = 1e7 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000000007;

int n, m, f[N][21], depth[N];
vector<int> edge[N];

void dfs(int u, int fa, int deep) {
    depth[u] = deep;
    f[u][0] = fa;
    for(int i = 1; i < 21; i++)
        f[u][i] = f[f[u][i - 1]][i - 1];
    for(int i = 0; i < edge[u].size(); i++) {
        int v = edge[u][i];
        if(v == fa) continue;
        dfs(v, u, deep + 1);
    }
}

PII cal(int u, int v) {
    if(depth[u] < depth[v]) swap(u, v);
    int ans = 0;
    for(int i = 20; i >= 0; i--) {
        if(!f[u][i]) continue;
        if(depth[f[u][i]] < depth[v]) continue;
        u = f[u][i];
        ans += (1 << i);
    }

    if(u == v) return mk(u, ans);

    for(int i = 20; i >= 0; i--) {
        if(!f[u][i] || !f[v][i]) continue;
        if(f[u][i] == f[v][i]) continue;
        u = f[u][i]; v = f[v][i];
        ans += 2 * (1 << i);
    }
    return mk(f[u][0], ans + 2);
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i < n; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs(1, 0, 0);
    while(m--) {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        PII ans = mk(inf, 0);
        PII t1 = cal(x, y), t2 = cal(x, z), t3 = cal(y, z);
        ans = min(ans, mk(t1.se + cal(t1.fi, z).se, t1.fi));
        ans = min(ans, mk(t2.se + cal(t2.fi, y).se, t2.fi));
        ans = min(ans, mk(t3.se + cal(t3.fi, x).se, t3.fi));
        printf("%d %d\n", ans.se, ans.fi);
    }
    return 0;
}

/*
*/

 

posted @ 2018-09-10 15:05  NotNight  阅读(79)  评论(0编辑  收藏  举报