LCA+最大生成树60pts,调得我心态炸了
查看原帖
LCA+最大生成树60pts,调得我心态炸了
174065
PeterWinchester楼主2021/9/9 21:29

求神犇救救蒟蒻吧!!!orz

#define N 10001
#define M 50001
#include <iostream>
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;

struct Edge {
	int from, next, to, len;
	bool operator < (const Edge& arg) const {
		return len > arg.len;
	}
} edge[M], tree[M];

int n, m, num_edge, num_tree, head_edge[N], dep[N], f[N][21], q, head_tree[N], fa[N], mi[N][21];

inline int read() {
	register char c = getchar();
	register int sign = 1, res = 0;
	while (!isdigit(c)) sign = c == '-' ? -1 : 1, c = getchar();
	while (isdigit(c)) res = res * 10 + c - 48, c = getchar();
	return sign * res;
}

void add_edge(int u, int v, int w) {
	edge[++num_edge].from = u;
	edge[num_edge].to = v;
	edge[num_edge].len = w;
	edge[num_edge].next = head_edge[u];
	head_edge[u] = num_edge;
}

void add_tree(int u, int v, int w) {
	tree[++num_tree].from = u;
	tree[num_tree].to = v;
	tree[num_tree].len = w;
	tree[num_tree].next = head_tree[u];
	head_tree[u] = num_tree;
}

void preprocess(int u, int father) {
	dep[u] = dep[father] + 1;
	f[u][0] = father;
	for (int i = 1; i <= 20; i++) {
		f[u][i] = f[f[u][i - 1]][i - 1];
		mi[u][i] = min(mi[u][i - 1], mi[f[u][i - 1]][i - 1]);
	}
	for (int i = head_tree[u]; i; i = tree[i].next) {
		int v = tree[i].to;
		if (v == father) continue;
		mi[v][0] = tree[i].len;
		preprocess(v, u);
	}
}

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

int get_min(int x, int y) {
	if (get_fa(x) != get_fa(y)) return -1;
	if (dep[x] < dep[y]) swap(x, y);
	int res = 0x7fffffff;
	for (int i = 20; i >= 0; i--) {
		if (dep[f[x][i]] >= dep[y]) {
		    res = min(res, mi[x][i]);
			x = f[x][i];
		}
		if (x == y) return res;
	}
	for (int i = 20; i >= 0; i--) {
		if (f[x][i] != f[y][i]) {
		    res = min(res, min(mi[x][i], mi[y][i]));
			x = f[x][i];
			y = f[y][i];
		}
	}
	return min(res, min(mi[x][0], mi[y][0]));
}

void merge(int x, int y) {
	fa[get_fa(x)] = get_fa(y);
}

void kruskal() {
	for (int i = 1; i <= n; i++) fa[i] = i;
	sort(edge + 1, edge + num_edge + 1);
	for (int i = 1; i <= num_edge; i++) {
		int u = edge[i].from, v = edge[i].to;
		if (get_fa(u) != get_fa(v)) {
			merge(u, v);
			add_tree(u, v, edge[i].len);
			add_tree(v, u, edge[i].len);
		}
	}
}

int main() {
	n = read(), m = read();
	for (int i = 1; i <= m; i++) {
		int u = read(), v = read(), w = read();
		add_edge(u, v, w);
		add_edge(v, u, w);
	}
	kruskal();
	for (int i = 1; i <= n; i++) {
		if (fa[i] == i) preprocess(i, 0);
	}
	q = read();
	for (int i = 1; i <= q; i++) {
		int x = read(), y = read();
	    printf("%d\n", get_min(x, y));
	}
	return 0;
}

2021/9/9 21:29
加载中...