ACM zoj 1789(并查集实现)
来源:互联网 发布:扭力单位转换软件 编辑:程序博客网 时间:2024/06/04 19:39
原文链接:http://blog.csdn.net/iqrocket/article/details/8134569
转载本博客上原创文章者,请注明出处。
这是道并查集的题目,刚开始我是用一个类来实现的。但很意外的是总是出现段错误(主要是指针乱指或者数组越界,但我发现不了这道题的问题),本来刚开始类的指针数据成员parent是指向动态申请的内存的,不行后改为一般的数组还是不行,最后还是将其改为非类来实现,结果AC了。(因此可能是ACM中最好不要用类实现的问题吧。)
程序如下:
- #include <iostream>
- #include <stdio.h>
- #include <memory.h>
- using namespace std;
- int parent[30001];
- //查找i所在的集合的元首,并对该树形结构进行优化
- int find(int r)
- {
- for(;parent[r]!=r;r=parent[r]); //直到它的根是其本身
- return r;
- }
- //将输入的组成员和其他相关联人员合并为一个集合
- void weightedUnion(int* arr,int num)
- {
- int root=find(arr[0]); //找到arr[0]所在集合的根
- for(int index=1;index<num;++index)
- {
- int r=find(arr[index]); //找到arr[index]所在的集合的根
- //如果集合的根不为root,则将其根置为root
- if(r!=root)
- parent[r]=root;
- }
- }
- //输出跟0在一组的人数,n表示人的总数
- int countSick(int i,int n)
- {
- int root=find(i); //找到这个结点的根
- int count=1; //这个只有自己这个结点时朋友数为1
- //每个非根结点都是以它所在树的树根为parent
- //从0结点的下一个结点开始算起
- for(int i=1;i<n;++i)
- {
- int r=find(i);
- if(r==root)
- ++count;
- }
- return count;
- }
- int main()
- {
- int N=0,M=0;
- int arr[30001];
- while(scanf("%d%d",&N,&M)!=EOF&&!(N==0&&M==0))
- {
- for(int i=0;i<N;++i)
- parent[i]=i;
- for(int i=0;i<M;++i)
- {
- int memNum=0;
- scanf("%d",&memNum);
- memset(arr,0,sizeof(arr)); //将数组元素都置为0
- for(int k=0;k<memNum;++k)
- scanf("%d",&arr[k]);
- weightedUnion(arr,memNum); //将成员并为一组
- }
- printf("%d\n",countSick(0,N)); //输出跟0在一组的成员数(0包括在内)
- }
- }
通过这道题我基本了解了并查集的基本操作,就是先查找出两个集合各自的集合首元素,再将它们合为同一个集合。
在查找集合的首元素的find函数中,我们也可以做先优化,如每次查找到一个元素后,找到其所在集合的首元素,再将这个元素到首元素的所有元素的parent都置为这个首元素。
- //查找i所在的集合的元首,并对该树形结构进行优化
- int collaspingFind(int i)
- {
- int r=i;
- for(;parent[r]>=0;r=parent[r]);
- //将i到集合首部元素的parent都保存集合的首元素r
- while(i!=r)
- {
- int s=parent[i];
- parent[i]=r;
- i=s;
- }
- return r;
- }
0 0
- ACM zoj 1789(并查集实现)
- ACM zoj 1789(并查集实现)
- ACM 并查集
- zoj 1789The Suspects 并查集
- zoj 1046(Jungle Roads)Kruskal 并查集实现
- zoj 3659 并查集
- zoj 3641 并查集
- zoj 3789 并查集
- zoj Friendship 并查集
- zoj 3659 并查集
- zoj 3641 并查集
- Zoj 3811并查集
- ZOJ 3789 并查集
- acm之并查集
- ACM-POJ并查集
- ACM之并查集
- ACM并查集浅谈
- ACM-数据结构-并查集
- 我的懒惰与畏难情绪
- Xcode 复制多行/移动某行/删除多行 快捷键
- 进程间通信WM_COPYDATA的基本实现
- jquery选择器
- Android模拟位置实现
- ACM zoj 1789(并查集实现)
- linux daemon 系统调用
- GCC编译过程中出错问题总结
- [Unity基础]三种截图方法
- Lost Cows(线段树 POJ2182)
- android 较高版本,页面分割线实现LinearLayoutCompat布局简单事例
- HDU 1686 Oulipo(KMP算法 字符串匹配)
- Linux终端设置代理
- hdoj 4307 Matrix 【最大流 求解矩阵乘最值】【经典构图!】