带权并查集HDU How Many Answers Are Wrong 题目链接
题意:给出m组 三个数x, y, v, 表示的含义是闭区间[x, y] 的权值为v, 让你计算出现矛盾的组数。
为什么要用并查集?以我现在的知识, 这种判断矛盾的好的解决方法貌似只有并查集这一种了。
如何判断真假呢,
首先我们输入三个整数x, y, v 只要找到 x == x && y == y && v == v 就可以判断他是真的了, 要是找不到了 就不确定了。
要怎么比?首先就是要找到一个基准(祖先)A 判断(y - A) - (x - A) ?= v 就行了呗。 就这样, 带权并查集就出来了
具体如何合并看下图
看ac代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <iostream> #include "algorithm" #include "cstdio" #include "set" #define esp 1e-6 using namespace std ;typedef long long ll;typedef unsigned long long ull;const int INF = 0x3f3f3f3f ;const int N = 2e5 + 5 ;int f[N], v[N];int tofind (int x) { if (f[x] != x){ int t = f[x]; f[x] = tofind(f[x]); v[x] += v[t]; } return f[x]; } void init (int n) { for (int i = 0 ; i <= n; i++){ f[i] = i; v[i] = 0 ; } } int main () { int n, m, a, b, c; while (cin >> n >> m){ init(n); int ans = 0 ; while (m--){ scanf ("%d%d%d" , &a, &b, &c); a--; int fa = tofind(a); int fb = tofind(b); if (fa != fb){ f[fa] = fb; v[fa] = -(v[a] + c - v[b]); } else { if (v[b] - v[a] != c) ans++; } } cout << ans << "\n" ; } return 0 ; }