推荐一个博客:https://blog.csdn.net/tribleave/article/details/72878239 并查集和带权并查集

带权并查集:在并查集的基础上,对其中的每一个元素赋有某些值。在对并查集进行路径压缩和合并操作时,这些权值具有一定属性,即可将他们与父节点的关系,变化为与所在树的根结点关系。

 

带权并查集习题:

1.(POJ1182)http://poj.org/problem?id=1182

推荐几个讲解详细的博客:https://blog.csdn.net/niushuai666/article/details/6981689 从向量的角度看问题

分析:难点在于:A.路径压缩时的关系域的更新

B.条件判断时,若两个点的根节点不同则合并;若根节点相同则按照当前给定关系与原本的关系进行判断。

总的来说就是两点之间的偏移量大小的确定

注意:改组只有一组,多组读入会WA

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=5e4+10;
 6 struct node{
 7     int pre;
 8     int realtion;
 9 }f[maxn];
10 
11 int find(int x)
12 {
13     if ( !f[x].pre ) return x;
14     int tmp=f[x].pre;
15     f[x].pre=find(tmp);
16     f[x].realtion=(f[x].realtion+f[tmp].realtion)%3;
17     return f[x].pre;
18 }
19 
20 int main()
21 {
22     int n,k,op,a,b,rt1,rt2,ans;
23     scanf("%d%d",&n,&k);
24     ans=0;
25     memset(f,0,sizeof(f));
26     for ( int i=1;i<=k;i++ )
27     {
28         scanf("%d%d%d",&op,&a,&b);
29         if ( a>n || b>n )
30         {
31             ans++;
32             continue;
33         }
34         if ( op==2 && a==b )
35         {
36             ans++;
37             continue;
38         }
39         rt1=find(a);
40         rt2=find(b);
41         if ( rt1!=rt2 )
42         {
43             f[rt2].pre=rt1;
44             f[rt2].realtion=(f[a].realtion+op-1+3-f[b].realtion)%3;
45         }
46         else
47         {
48             if ( op==1 && f[a].realtion!=f[b].realtion )
49             {
50                 ans++;
51                 continue;
52             }
53             if ( op==2 && ((3-f[a].realtion+f[b].realtion)%3!=1) )
54             {
55                 ans++;
56                 continue;
57             }
58         }
59     }
60     printf("%d\n",ans);
61     return 0;
62 }
POJ1182

相关文章:

  • 2021-07-14
  • 2022-01-11
  • 2022-03-01
  • 2022-02-26
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-10-06
  • 2021-12-27
  • 2021-05-28
  • 2022-12-23
相关资源
相似解决方案