hdu3038How Many Answers Are Wrong(带权并查集)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038

题解转载自https://www.cnblogs.com/liyinggang/p/5327055.html

题目大意:有n个数,你不知道具体是啥,只知道有n个,然后输入m组数据,每组包含三个整数,a,b,s,表示区间[a,b]的整数和为s,输出有错误的数据的组数。

解题思路:是个典型的带权并查集,难点就在于更新相对信息值。在查找和合并也要对相对信息值进行更新。

做法是用一个数组存储某个节点到其根节点的距离。把区间的总和看成是两个端点的相对距离。

极力推荐这位大牛的博客:http://blog.csdn.net/niushuai666/article/details/6981689

这题让我学到了很多,特别是关于向量偏移,可以直接找到根节点与子节点的关系

 

这题我们利用一个sum[]数组保存从某点到其祖先节点距离。

1.从上图我们可以看出,当roota!=rootb时 如果将roota并入rootb,那么是不是 roota->rootb = b->rootb - b->roota

然后我们可以知道 b->roota = a->roota - a->b

所以最后可以推出 roota ->rootb = b->rootb + a->b - a->roota

而roota的根节点是rootb,所以 roota->rootb = sum[roota]

然后依次推出得到 sum[roota] = -sum[a]+sum[b]+v (这里的a要说明一下由于是区间 [a,b] ,[a,b] = [root,b]-[root,a-1],所以a要减一)

2.如果roota==rootb 是不是 a和b的根节点已经相同了?所以我们只要验证 a->b是否与题中的长度一致了。

所以 a->b = a->root - b->root

然后得到表达式 v = sum[a]-sum[b] (一定要记住这里的sum都是相对于根节点的,sum的更新在路径压缩的时候更新了)

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 const int maxn=200005;
 6 int par[maxn],rank[maxn],ans;
 7 
 8 int find(int x)
 9 {
10     if(par[x]==x)
11         return x;
12     int temp=find(par[x]);
13     rank[x]+=rank[par[x]];
14     return par[x]=temp;
15 }
16 
17 void unite(int x,int y,int s)
18 {
19     int rootx=find(x);
20     int rooty=find(y);
21     if(rootx!=rooty)
22     {
23         par[rooty]=rootx;
24         rank[rooty]=rank[x]+s-rank[y];  //用向量的思维,合并后rooy到rootx的距离就等于x到根距离加上x和y的距离减去y到rooty的距离 
25     }
26     else
27     {
28         if(rank[x]+s!=rank[y])
29             ans++;
30     }
31 }
32 
33 signed main()
34 {
35     int n,m;
36     while(scanf("%d%d",&n,&m)!=EOF)
37     {
38         for(int i=1;i<=n;i++)
39             par[i]=i,rank[i]=0;
40         ans=0;
41         while(m--)
42         {
43             int a,b,s;
44             scanf("%d%d%d",&a,&b,&s);
45             a--;
46             unite(a,b,s);
47         }
48         printf("%d
",ans);
49     }
50     return 0;
51 }
52  
原文地址:https://www.cnblogs.com/zjl192628928/p/9445382.html