带权并查集(思路感觉挺自然的, 但是不知道哪错了)
查看原帖
带权并查集(思路感觉挺自然的, 但是不知道哪错了)
675527
Play_CP_4fun楼主2022/12/2 05:34
/*
Author: SJ

general 
1.shuzu buyao kai xiaole
2.0 1 zhe liangge tepan
3.dfs jide biaoji qidian
4.changdaima jide fenbu tiaoshi
5.yao xihuanshang heihezi

str
1.yongle s.substr(), jide kanyixiashibushikeyi yigeyige shuchu

THINK TWICE, CODE ONCE.
Duo xiang ti, Shao jiao lv.
*/
#include<bits/stdc++.h>
const int N = 1e5 + 10;
using ll = long long;
using ull = unsigned long long;
/*
val[x]记录的是(x, fa[x]]这个左开右闭区间的区间和,
唯一一种矛盾的情况就是, 两个小区间没有重叠拼出的大区间和(或者是一大一小两个区间
减出来的小区间), 与事实不符.

(为什么是只有这种情况的, 我也不会证明...)
*/
int w, fa[110], val[110];
void init() {
	for (int i = 0; i <= 20; i++) fa[i] = i;
}
int find(int x) {
	if (x != fa[x]) {
		int t = fa[x];
		fa[x] = find(fa[x]);
		val[x] += val[t];
	}
	return fa[x];
}
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	std::cin >> w;
	while (w--) {
		int n, m;
		bool mark = true;
		std::cin >> n >> m;

		init();
		for (int i = 0; i < m; i++) {
			int s, t, v;
			std::cin >> s >> t >> v;
			s--;
			int xx = find(s);
			int yy = find(t);

			if (xx == yy) {
				if (val[s] - val[t] != v) {
					mark = false;
				}
			} else {
				if (xx > yy) {
					fa[yy] = xx;
					val[yy] = val[s] - v - val[t];
				} else {
					fa[xx] = yy;
					val[xx] = v + val[t] - val[s];
				}
			}
		}

		// for (int i = 0; i <= n; i++) {
		// 	std::cout << fa[i] << ' ' << val[i] << "\n";
		// }
		if (mark) std::cout << "true" << "\n";
		else std::cout << "false" << "\n";
	}
	return 0;
}

求调

2022/12/2 05:34
加载中...