Loading

HDU-2874 Connections between cities

Connections between cities

LCA 倍增板子

求距离维护一个前缀和,\(dis(u, v) = dis(rt, u) + dis(rt, v) - dis(rt, lca) * 2\)

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
#define pii pair<int, ll>
const int maxn = 1e4 + 10;
vector<pii>gra[maxn];
int vis[maxn], fa[maxn][15], dep[maxn];
ll sum[maxn];

void dfs(int now, int pre, int d)
{
    if(vis[now]) return;
    vis[now] = 1;
    fa[now][0] = pre;
    dep[now] = d;
    for(pii &a : gra[now])
    {
        if(a.first == pre) continue;
        sum[a.first] += sum[now] + a.second;
        dfs(a.first, now, d + 1);
    }
}

void init(int n)
{
    for(int i=0; i<=n; i++) dep[i] = sum[i] = vis[i] = 0;
    for(int i=1; i<=n; i++) dfs(i, i, 1);
    for(int i=1; i<15; i++)
        for(int j=1; j<=n; j++)
            fa[j][i] = fa[fa[j][i - 1]][i - 1];
    for(int i=0; i<=n; i++) gra[i].clear();
}

int LCA(int u, int v)
{
    if(dep[u] < dep[v]) swap(u, v);
    int dif = dep[u] - dep[v];
    for(int i=14; i>=0; i--)
    {
        if(dif >= (1 << i))
        {
            dif -= 1 << i;
            u = fa[u][i];
        }
    }
    if(u == v) return u;
    for(int i=14; i>=0; i--)
    {
        if(fa[u][i] != fa[v][i])
        {
            u = fa[u][i];
            v = fa[v][i];
        }
    }
    return fa[u][0];
}

ll dis(int u, int v)
{
    int lca = LCA(u, v);
    return sum[u] - sum[lca] * 2 + sum[v];
}

int main()
{
    int n, m, q;
    while(scanf("%d%d%d", &n, &m, &q) != EOF)
    {
        for(int i=0; i<m; i++)
        {
            int a, b;
            ll c;
            scanf("%d%d%lld", &a, &b, &c);
            gra[a].push_back({b, c});
            gra[b].push_back({a, c});
        }
        init(n);
        while(q--)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            if(fa[u][14] != fa[v][14]) printf("Not connected\n");
            else printf("%lld\n", dis(u, v));
        }
    }
    return 0;
}
posted @ 2022-07-28 16:44  dgsvygd  阅读(30)  评论(0编辑  收藏  举报