题目链接
思路:
由题意给定几组判断,如果与前面的相悖则为错误ans++,如果与前面不相悖则加入维护,
用带权的并查集维护给出的条件,l~r和为s,可以看成d[r]-d[l-1]==s和前缀和类似。
代码:
#include#define fastio ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL) #define debug(a) cout << "debug : " << (#a) << " = " << a << endl using namespace std; typedef long long ll; typedef pair PII; const int N = 2e5 + 10; const int INF = 0x3f3f3f3f; const double eps = 1e-6; const int mod = 998244353; int n, m; int ans; int f[N], d[N]; int find(int x) { if (x != f[x]) { int u = find(f[x]); //递归找x的根节点 //回溯更新 d[x] += d[f[x]]; //将x到新根节点的距离更新为原来:原来根据点到新根节点 + x到原来根节点 f[x] = u; //更新x根节点 } return f[x]; } //x所在的树根节点加入到y所在的树下方 void join(int x, int y, int w) { int f1 = find(x), f2 = find(y); f[f1] = f2; //x的父节点成为y父节点的子节点 d[f1] = d[y] + w - d[x]; //将f1节点加到以f2为根据点的树下 } int main() { fastio; while (cin >> n >> m) { ans = 0; for (int i = 0; i <= n; i++) f[i] = i, d[i] = 0; while (m--) { int l, r, w; cin >> l >> r >> w; l--; if (find(l) == find(r)) { if (d[l] - d[r] != w) //因为合并都是将l所在的树加入到r所在的树,所以d[l] - d[r]为正数 ans++; } else join(l, r, w); } cout << ans << endl; } return 0; }



