[LuoGu2245]星际导航

Description

[LuoGu2245]星际导航

Solution

好像叫作最小瓶颈路问题
就是把原图求最小生成树,然后在树上跑\(\text{LCA}\)的最大值
如果不在一个一颗树上,就输出\(\text{impossible}\)
玄学证明不会

Code

#include<bits/stdc++.h>
using namespace std;
#define N 800010
struct rec {
    int nxt, ver, val;
} t[N];
struct Rec {
    int u, v, w;
} e[N];
int n, m, q, cnt, tot, u, v;
int fa[N], head[N], deep[N], f[N][21], h[N][21];
inline int read() {
    int s = 0, w = 1;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
    for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
    return s * w;
}
int find(int x) {
    if (fa[x] == x) return x;
    return fa[x] = find(fa[x]);
}
inline void Merge(int x, int y) {
    fa[find(x)] = find(y);
}
inline bool cmp(Rec x, Rec y) {
    return x.w < y.w;
}
inline void add(int u, int v, int w) {
    t[++cnt].nxt = head[u], t[cnt].ver = v, t[cnt].val = w, head[u] = cnt;
}
inline void Init() {
    for (register int i = 1; i <= n; i++)
        fa[i] = i;
}
inline void kruskal() {
    sort(e + 1, e + m + 1, cmp);
    for (register int i = 1; i <= m; i++) {
        int eu = find(e[i].u), ev = find(e[i].v);
        if (eu == ev) continue;
        add(e[i].u, e[i].v, e[i].w), add(e[i].v, e[i].u, e[i].w);
        fa[ev] = eu;
        ++tot;
        if (tot == n - 1) break;
    }
}
void DFS(int u, int fa, int w) {
    deep[u] = deep[fa] + 1;
    f[u][0] = fa, h[u][0] = w;
    for (register int i = 1; i <= 20; i++)
        f[u][i] = f[f[u][i - 1]][i - 1],
        h[u][i] = max(h[u][i - 1], h[f[u][i - 1]][i - 1]);
    for (register int i = head[u]; i; i = t[i].nxt) {
        int v = t[i].ver;
        if (v != fa)
            DFS(v, u, t[i].val);
    }
}
inline int LCA(int u, int v) {
    int ans = 0;
    if (deep[u] < deep[v]) swap(u, v);
    for (register int i = 20; i >= 0; i--)
        if (deep[f[u][i]] >= deep[v]) {
            ans = max(ans, h[u][i]);
            u = f[u][i];
        }
    if (u == v) return ans;
    for (register int i = 20; i >= 0; i--)
        if (f[u][i] != f[v][i]) {
            ans = max(ans, h[u][i]), ans = max(ans, h[v][i]);
            u = f[u][i], v = f[v][i];
        }
    ans = max(ans, h[u][0]), ans = max(ans, h[v][0]);
    return ans;
}
int main() {
    //freopen("a.in", "r", stdin);
    //freopen("1.out", "w", stdout);
    n = read(), m = read();
    for (register int i = 1; i <= m; i++)
        e[i].u = read(), e[i].v = read(), e[i].w = read();
    Init();
    kruskal();
    for (register int i = 1; i <= n; i++)
        if (!deep[i])
            DFS(i, 0, 0);
    q = read();
    for (register int i = 1; i <= q; i++) {
        u = read(), v = read();
        if (find(u) != find(v))
            printf("impossible\n");
        else
            printf("%d\n", LCA(u, v));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Agakiss/p/11827947.html