POJ 1611 The Suspects (并查集)不相交集合+合并优化
2016-07-26 01:40
405 查看
传送门:POJ 1611 The Suspects (并查集)
父节点里面保存的是元素的能到达的子节点
下面说一下并查集的优化,按照每棵树的高度来区分那个是作为父节点。
题目大意
有很多组学生,在同一个组的学生经常会接触,也会有新的同学的加入。但是SARS是很容易传染的,只要在改组有一位同学感染SARS,那么该组的所有同学都被认为得了SARS。现在的任务是计算出有多少位学生感染SARS了。假定编号为0的同学是得了SARS的。解题思路
向这种题目明显是并查集的一种变形叫不相交并查集。父节点里面保存的是元素的能到达的子节点
下面说一下并查集的优化,按照每棵树的高度来区分那个是作为父节点。
AC代码
#include<cstdio> #include<cstring> const int MAXN = 30010; int pre[MAXN],rank[MAXN],sum[MAXN]; int N,M; void makeSet() { int i; for(i=0;i<N;i++) pre[i] = i,rank[i] = 0,sum[i] = 1; } int find(int x) { return (x == pre[x])? pre[x] : (pre[x] = find(pre[x])); } void join(int x,int y) { int fx = find(x),fy = find(y); if(fx == fy) return ; //sum[父节点]保存的是连通的数量 if(rank[fx]<rank[fy]) pre[fx] = fy,sum[fy] += sum[fx]; //rank[]数组就是优化,每次把 else if(rank[fx] == rank[fy]) pre[fx] = fy,sum[fy]+=sum[fx],rank[fy]++; else pre[fy] = fx,sum[fx] += sum[fy]; } int main() { int k,a,b; while(~scanf("%d%d",&N,&M)) { if(M==0 && N==0) break; if(M==0) { printf("1\n"); continue; } makeSet(); for(int j=0;j<M;j++) { scanf("%d%d",&k,&a); for(int i=1;i<k;i++) { scanf("%d",&b); join(a,b); } } printf("%d\n",sum[find(0)]); } return 0; }
相关文章推荐
- 智能指针 auto_ptr、scoped_ptr、shared_ptr、weak_ptr
- 多线程编程入门(3):线程状态图
- 2016/7/25第一天--闲谈
- 士兵突击有感
- Gym 100541 B. Sum 分块的技巧、思维题、Interesting
- 抗生素以及为什么要慎用抗生素?
- Visual Studio 2015编写wxWidgets程序
- [leetcode] Combination Sum IV
- poj 1862
- 【POJ 3321】Apple Tree
- error 1044 (42000):access denied for user ''@'l...解决方法
- 迷宫最短路径的步数
- 在linux下如何将文件夹打包
- HDOJ-----1873简单优先队列
- Codeforces292D Connected Components 经典好题并查集
- SCU 4531 Cruel War II(DFS)
- 如何让指定的项目成为tomcat的默认项目
- UVA10020->贪心
- 【转】一看就明白的爬虫入门讲解:基础理论篇
- [React Native] Error Handling and ActivityIndicatorIOS