只得了10分的蒟蒻求助
查看原帖
只得了10分的蒟蒻求助
217577
kemkra楼主2020/9/6 09:44
#include <cstdio>
#include <algorithm>

using namespace std;

const int INF = 0x7fffffff;
const int MAXN = 50001;
const int MAXM = 50001;
const int MAXLOG = 21;

struct Edge {
    int from;
    int to;
    int val;
} edge[MAXN];

struct CFS {
    int to;
    int next;
    int val;
} mst[MAXM * 2];

int n, m, x, y, z, q;
int head[MAXN], tot;
int fa[MAXN], dep[MAXN];
int anc[MAXN][MAXLOG], w[MAXN][MAXLOG];
bool vis[MAXN];

void add(int from, int to, int val) {
    mst[++tot].to = to;
    mst[tot].val = val;
    mst[tot].next = head[from];
    head[from] = tot;
}

bool cmp(Edge x, Edge y) {
    return x.val > y.val;
}

int find(int x) {
    if (fa[x] != x) fa[x] = find(fa[x]);
    return fa[x];
}

void kruskal() {
    for (int i = 1; i <= n; i++) fa[i] = i;
    sort(edge + 1, edge + m + 1, cmp);
    for (int i = 1; i <= m; i++) {
        int f = find(edge[i].from), t = find(edge[i].to);
        if (f != t) {
            add(edge[i].from, edge[i].to, edge[i].val);
            add(edge[i].to, edge[i].from, edge[i].val);
            fa[f] = t;
        }
    }
}

void dfs(int x) {
    vis[x] = 1;
    for (int i = head[x]; i; i = mst[i].next) {
        int to = mst[i].to;
        if (!vis[to]) {
            dep[to] = dep[x] + 1;
            anc[to][0] = x;
            w[to][0] = mst[i].val;
            dfs(to);
        }
    }
}

void init() {
    for (int i = 1; i < MAXLOG; i++)
        for (int j = 1; j <= n; j++) {
            anc[j][i] = anc[anc[j][i - 1]][i - 1];
            w[j][i] = min(w[j][i - 1], w[anc[j][i - 1]][i - 1]);
        }
}

int getlca(int x, int y) {
    if (find(x) != find(y)) return -1;
    int ans = INF;
    if (dep[x] < dep[y]) swap(x, y);
    for (int i = MAXLOG - 1; i >= 0; i--)
        if (dep[anc[x][i]] >= dep[y]) {
            ans = min(ans, min(w[x][i], w[y][i]));
            x = anc[x][i];
        }
    ans = min(ans, min(w[x][0], w[y][0]));
    return ans;
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i++) {
        scanf("%d%d%d", &x, &y, &z);
        edge[i].from = x;
        edge[i].to = y;
        edge[i].val = z;
    }
    kruskal();
    for (int i = 1; i <= n; i++)
        if (!vis[i]) {
            dep[i] = 1;
            dfs(i);
            anc[i][0] = 1;
            w[i][0] = INF;
        }
    init();
    scanf("%d", &q);
    for (int i = 1; i <= q; i++) {
        scanf("%d%d", &x, &y);
        printf("%d\n", getlca(x, y));
    }
    return 0;
}
2020/9/6 09:44
加载中...