题目链接
题意
玩游戏,每次说a到b区间的和为S,但是可能与以前说的相悖。计算错了多少次。
解析
a到b区间的和,等价于b的权值比a-1的权值大S。这样就转化为普通带权并查集。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn = 200000+100;
int fa[maxn];
int dis[maxn];
void init() {
for (int i=0; i<maxn; i++)
fa[i] = i, dis[i] = 0;
}
int Find(int x) {
if (x == fa[x])
return x;
int t = Find(fa[x]);
dis[x] += dis[fa[x]];
return fa[x] = t;
}
int Union(int u, int v, int w) {
int x = Find(u);
int y = Find(v);
if (x == y && dis[v] != dis[u]+w)
return 1;
dis[y] = dis[u]-dis[v]+w;
fa[y] = x;
return 0;
}
int main() {
int n, m;
while(~scanf("%d%d", &n, &m)) {
init();
int ans=0;
for (int i=0; i<m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w); //u到v和等价于v大于u-1的值。
u = u-1;
if (Union(u, v, w))
ans++;
}
printf("%d\n", ans);
}
return 0;
}