需要解析
  • 板块学术版
  • 楼主Sukilin
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/11/2 22:20
  • 上次更新2024/11/3 10:31:39
查看原帖
需要解析
959201
Sukilin楼主2024/11/2 22:20

P1967 我用的 Kruskal 重构树,但是注释处如果按照题目数据范围来写,第一个 Subtask 最后几个点还会 RE,这样写才能过,为什么

#include <iostream>
#include <cstdio>
#include <algorithm>
const int N = 1e6 + 7; //here
const int M = 5e6 + 7;
const int J = 30;
class edge {
	public:
		int tail;
		int head;
		int weight;
		friend bool operator < (edge x, edge y) {
			return x.weight < y.weight;
		}
		friend bool operator > (edge x, edge y) {
			return x.weight > y.weight;
		}
};
edge e[M];
int o;
int lch[N << 1], rch[N << 1];
int wei[N << 1];
bool vis[N << 1];
int cnt;
int fak[J][N << 1], dep[N << 1];
int logn[N << 1];
int n, m;
int q;
int fas[N << 1];
inline void add(int x, int y, int w) {
	e[o++] = (edge){x, y, w};
}
int find(int x) {
	return x == fas[x] ? x : (fas[x] = find(fas[x]));
			std::cout << "de\n";
}
void kruskal() {
	std::sort(e, e + m, std::greater <edge>());
	for(int i = 0; i < m; i++) {
		int u = e[i].tail, v = e[i].head;
		u = find(u), v = find(v);
		if(u != v) {
			cnt++;
			fas[v] = cnt;
			fas[u] = cnt;
			lch[cnt] = u;
			rch[cnt] = v;
			wei[cnt] = e[i].weight;
		}
	}
}
void init(int u, int f) {
	fak[0][u] = f;
	dep[u] = dep[f] + 1;
	for(int i = 1; i <= logn[dep[u]]; i++)
		fak[i][u] = fak[i - 1][fak[i - 1][u]];
	if(lch[u] != 0) init(lch[u], u);
	if(rch[u] != 0) init(rch[u], u);
}
int cal(int x, int y) {
	if(find(x) != find(y)) return -1;
	int rt = find(x);
	if(!vis[rt]) init(rt, 0), vis[rt] = true;
	if(dep[x] > dep[y]) std::swap(x, y);
	for(int i = logn[dep[y]]; i >= 0; i--)
		if(dep[fak[i][y]] >= dep[x])
			y = fak[i][y];
	if(x == y) return wei[x];
	for(int i = logn[dep[y]]; i >= 0; i--)
		if(fak[i][x] != fak[i][y])
			x = fak[i][x], y = fak[i][y];
	return wei[x == y ? x : fak[0][x]];
}
int main() {
	std::freopen("test.in", "r", stdin);
	std::cin >> n >> m;
	cnt = n;
	logn[1] = 0;
	for(int i = 1; i <= n; i++)
		logn[i] = logn[i / 2] + 1;
	for(int i = 1; i <= 2 * n + 1; i++)
		fas[i] = i;
	int x, y, z;
	for(int i = 0; i < m; i++) {
		std::cin >> x >> y >> z;
		add(x, y, z);
	}
	kruskal();
	std::cin >> q;
	for(int i = 0; i < q; i++) {
		std::cin >> x >> y;
		std::cout << cal(x, y) << '\n';
	}
	return 0;
}
2024/11/2 22:20
加载中...