【数据结构】并查集之二

前端之家收集整理的这篇文章主要介绍了【数据结构】并查集之二前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1. 两类类别


并查集中有两类类别,即并查集中元素要么属于集合A,要么属于B,且A与B不相交。

利用向量得到关系:



1.1 POJ 2492


代码:

  1. #include "stdio.h"
  2.  
  3. int parent[2000],relation[2000];
  4.  
  5. int find(int x)
  6. {
  7. int root,tail,temp;
  8. if(parent[x]==x)
  9. return x;
  10. else
  11. {
  12. for(root=x;parent[root]!=root;root=parent[root]);
  13. for(tail=x;tail!=root;)
  14. {
  15. temp=parent[tail];
  16. parent[tail]=root;
  17. tail=temp;
  18. }
  19. return root;
  20. }
  21. }
  22.  
  23. void update(int yroot,int n)
  24. {
  25. int i;
  26. for(i=1;i<=n;i++)
  27. {
  28. if(i!=yroot&&find(i)==yroot)
  29. relation[i]=(relation[i]+relation[yroot])%2;
  30. }
  31. }
  32.  
  33. void root_union(int x,int y,int xroot,int yroot,int n)
  34. {
  35. relation[yroot]=(relation[x]-relation[y]+1)%2;
  36. update(yroot,n);
  37. parent[yroot]=xroot;
  38. }
  39.  
  40.  
  41. int main()
  42. {
  43. int scena_num,bug_num,intera_num,a,b,i,count;
  44. int aroot,broot,suspi_flag;
  45. scanf("%d",&scena_num);
  46. for(count=1;count<=scena_num;count++)
  47. {
  48. scanf("%d%d",&bug_num,&intera_num);
  49. suspi_flag=0;
  50. for(i=1;i<=bug_num;i++)
  51. {
  52. parent[i]=i;
  53. relation[i]=0;
  54. }
  55. while(intera_num--)
  56. {
  57. scanf("%d%d",&a,&b);
  58. aroot=find(a);
  59. broot=find(b);
  60. if(aroot!=broot)
  61. {
  62. root_union(a,aroot,bug_num);
  63. }
  64. else
  65. {
  66. if(relation[a]!=(relation[b]+1)%2)
  67. suspi_flag=1;
  68. }
  69. }
  70. if(suspi_flag==1)
  71. printf("Scenario #%d:\nSuspicIoUs bugs found!\n\n",count);
  72. else
  73. printf("Scenario #%d:\nNo suspicIoUs bugs found!\n\n",count);
  74. }
  75. return 0;
  76. }

1.2 POJ 1703


代码:

  1. #include "stdio.h"
  2.  
  3. int parent[100000],relation[100000];
  4.  
  5. int find(int x) //寻找root结点,并更新parent链域的relation值
  6. {
  7. int temp;
  8. if(parent[x]==x)
  9. return x;
  10. temp=parent[x];
  11. parent[x]=find(parent[x]);
  12. relation[x]=(relation[x]+relation[temp])%2;
  13. return parent[x];
  14. }
  15.  
  16. int main()
  17. {
  18. int T,N,M,b;
  19. int aroot,broot;
  20. char message;
  21. scanf("%d",&T);
  22. while(T--)
  23. {
  24. scanf("%d%d",&N,&M);
  25. for(i=1;i<=N;i++)
  26. {
  27. parent[i]=i;
  28. relation[i]=0;
  29. }
  30. while(M--)
  31. {
  32. getchar();
  33. scanf("%c%d%d",&message,&b);
  34. aroot=find(a);
  35. broot=find(b);
  36. if(message=='A')
  37. {
  38. if(N==2&&a!=b)
  39. printf("In different gangs.\n");
  40. else
  41. {
  42. if(aroot==broot)
  43. {
  44. if(relation[a]==relation[b])
  45. printf("In the same gang.\n");
  46. else
  47. printf("In different gangs.\n");
  48. }
  49. else
  50. printf("Not sure yet.\n");
  51. }
  52. }
  53. else
  54. {
  55. if(aroot!=broot)
  56. {
  57. parent[broot]=aroot;
  58. relation[broot]=(relation[a]-relation[b]+1)%2;
  59. }
  60. }
  61. }
  62. }
  63. return 0;
  64. }


2. 三类类别


并查集中元素属于互不相交的集合A,B,C。


类似地,可以得到如下关系:

r[y]=(r[x]+d)%3 //不能得到r[x]=(r[y]+d)%3

r[yroot]=(r[x]-r[y]+d+3)%3 //+3,是因为r[x]-r[y]+d有可能为负数

其中,0表示与root节点同类,1表示吃root节点,2表示被root节点吃。


2.1POJ 1182


代码:

  1. #include "stdio.h"
  2.  
  3. int parent[50000],relation[50000];
  4.  
  5. int find(int x)
  6. {
  7. int temp;
  8. if(parent[x]==x)
  9. return x;
  10. temp=parent[x];
  11. parent[x]=find(parent[x]);
  12. relation[x]=(relation[x]+relation[temp])%3;
  13. return parent[x];
  14. }
  15.  
  16. int main()
  17. {
  18. int num_ani,num_sta,statement,count=0;
  19. int a,d;
  20. scanf("%d%d",&num_ani,&num_sta);
  21. for(i=1;i<=num_ani;i++)
  22. {
  23. parent[i]=i;
  24. relation[i]=0;
  25. }
  26. while(num_sta--)
  27. {
  28. getchar();
  29. scanf("%d%d%d",&statement,&b);
  30. d=statement-1;
  31. if(a>num_ani||b>num_ani)
  32. count++;
  33. else
  34. {
  35. aroot=find(a);
  36. broot=find(b);
  37. if(aroot!=broot)
  38. {
  39. parent[broot]=aroot;
  40. relation[broot]=(relation[a]-relation[b]+d+3)%3;
  41. }
  42. else if(relation[b]!=(relation[a]+d)%3||(d==1&&a==b))
  43. count++;
  44. }
  45. }
  46. printf("%d\n",count);
  47. return 0;
  48. }

猜你在找的数据结构相关文章