InputLine 1: Two integers, N and M (1 <= N <= 200000, 1 <= M <= 40000). Means TT wrote N integers and FF asked her M questions.
Line 2..M+1: Line i+1 contains three integer: Ai, Bi and Si. Means TT answered FF that the sum from Ai to Bi is Si. It‘s guaranteed that 0 < Ai <= Bi <= N.
You can assume that any sum of subsequence is fit in 32-bit integer.
OutputA single line with a integer denotes how many answers are wrong.
不清楚带权并查集的点这里 ----> 传送门
思路:根据带权并查集的套路,我们可以直接考虑两种情况:
①fax == fay 则我们直接判断fa[x].v + d 与 fa[y].v是否相同就可以了
②fax != fay 则直接合并,fa[fay].rt = fay, fa[fay].v = fa[x].v + d - fa[y].v。因为两者未合并过,则他们两个区间的单位数值可以是任意的,合并了不过是确定了区间的数值,单位数值可以是负数。
这里有个细节问题,因为我们求得是 A[R] - A[L-1] = D,则输入了L,R,我们应该让L-1再进行操作。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <queue> 5 #include <vector> 6 #include <cmath> 7 8 using namespace std; 9 10 #define ll long long 11 #define pb push_back 12 #define fi first 13 #define se second 14 15 const int N = 2e5 + 10; 16 struct node 17 { 18 int rt, v; 19 }fa[N]; 20 int n, m; 21 22 int Find(int x) 23 { 24 if(fa[x].rt == x){ 25 return x; 26 }else{ 27 int tmp = fa[x].rt; 28 fa[x].rt = Find(fa[x].rt); 29 fa[x].v += fa[tmp].v; 30 return fa[x].rt; 31 } 32 } 33 34 bool Union(int x, int y, int d){ 35 int fax = Find(x); 36 int fay = Find(y); 37 //if(fax > fay) swap(fax, fay); 38 if(fax == fay){ 39 if(0 == fa[x].v + d - fa[y].v) return true; 40 else return false; 41 } 42 else if(fax != fay){ 43 fa[fay].rt = fax; 44 fa[fay].v = fa[x].v + d - fa[y].v; 45 return true; 46 } 47 } 48 49 void solve() 50 { 51 while(~scanf("%d%d", &n, &m)){ 52 for(int i = 0; i <= n; ++i) fa[i].rt = i, fa[i].v = 0; 53 54 int ans = 0; 55 for(int i = 1; i <= m; ++i){ 56 int x, y, d; 57 scanf("%d%d%d", &x, &y, &d); 58 --x; 59 if(!Union(x, y, d)) ++ans; 60 } 61 62 //printf("ans = %d\n", ans); 63 printf("%d\n", ans); 64 } 65 } 66 67 int main() 68 { 69 70 solve(); 71 72 return 0; 73 }
How Many Answers Are Wrong HDU - 3038 (带权并查集)
原文:https://www.cnblogs.com/SSummerZzz/p/13268903.html