思路:以区间标号大的为根建树,sum[a] 表示从a+1开始到当前根节点的和。剩下的就是并查集的操作了。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 200100;
int p[N], sum[N];
int ans, n, m;
void init() {
int i;
ans = 0;
memset(sum, 0, sizeof(sum));
for (i = 0; i <= n; ++i)
p[i] = i;
}
int find_set(int x) {
if (p[x] == x)
return x;
int t = p[x];
p[x] = find_set(p[x]);
sum[x] += sum[t];
return p[x];
}
void union_set(int a, int b, int pa, int pb, int c) {
if (pa > pb) {
p[pb] = pa;
sum[pb] = sum[a] - sum[b] - c;
}
else {
p[pa] = pb;
sum[pa] = sum[b] + c - sum[a];
}
}
int main()
{
int i, a, b, c, pa, pb;
while (scanf("%d %d", &n, &m) != EOF) {
init();
for (i = 0; i < m; ++i) {
scanf("%d %d %d", &a, &b, &c);
a--;
pa = find_set(a);
pb = find_set(b);
if (pa == pb) {
if (sum[a] != sum[b] + c) {
ans++;
}
}
else
union_set(a, b, pa, pb, c);
}
printf("%d\n", ans);
}
return 0;
}