BZOJ 3732: Network

kruskal重构树
因为建出来的树有大根堆性质,而且kruskal过程是优先考虑短的边的
所以LCA处的值一定是最短的最长边

#include <bits/stdc++.h>

char buf[1 << 21], *p1 = buf, *p2 = buf;
inline char getc() {
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline int read() {
    int x = 0, f = 1; char ch = getc();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getc(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getc(); }
    return x * f;
}

const int N = 3e4 + 7;
struct Edge {
    int u, v, c;
    bool operator < (const Edge &p) const {
        return c < p.c;
    }
    void in() {
        u = read(), v = read(), c = read();
    }
} edge[N];
int n, m, q, pa[N], fa[N][18], head[N], to[N], ne[N], cnt = 1, c[N];
int dep[N];
inline int find(int x) { return x == pa[x] ? x : pa[x] = find(pa[x]); }
inline void add(int u, int v) { to[++cnt] = v; ne[cnt] = head[u]; head[u] = cnt; }

void dfs(int u) {
    for (int i = 1; (1 << i) <= dep[u]; i++)
        if (fa[u][i - 1]) fa[u][i] = fa[fa[u][i - 1]][i - 1];
    for (int i = head[u]; i; i = ne[i]) {
        int v = to[i];
        dep[v] = dep[u] + 1;
        dfs(v);
    }
}

int Lca(int u, int v) {
    if (dep[u] < dep[v]) std::swap(u, v);
    int dif = dep[u] - dep[v];
    for (int i = 16; ~i; i--)
        if (dif >> i & 1)
            u = fa[u][i];
    if (u == v) return u;
    for (int i = 16; ~i; i--)
        if (fa[u][i] != fa[v][i])
            u = fa[u][i], v = fa[v][i];
    return fa[u][0];
}

int main() {
    n = read(), m = read(), q = read();
    for (int i = 0; i < m; i++)
        edge[i].in();
    std::sort(edge, edge + m);
    for (int i = 1; i <= 2 * n; i++) 
        pa[i] = i;
    for (int i = 0; i < m; i++) {
        int u = find(edge[i].u), v = find(edge[i].v);
        if (u == v) continue;
        int node = ++n;
        add(node, u), add(node, v);
        c[node] = edge[i].c;
        pa[u] = pa[v] = node;
        fa[u][0] = fa[v][0] = node;
    }
    for (int i = n; i; i--)
        if (!dep[i]) dep[i] = 1, dfs(i);
    for (int x, y; q--; ) {
        x = read(), y = read();
        printf("%d\n", c[Lca(x, y)]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Mrzdtz220/p/12327213.html