九度OJ-1444:More is better(用并查集求集合大小)
2017-02-09 01:16
441 查看
本题可抽象为求各个连通子图的顶点数的最大值。进一步抽象为求各个集合的个数的最大值。同样采用并查集实现集合的合并。
以下有两个版本。改进版是看完《机试指南》后启发,将统计集合元素数的操作封装进了unionSet函数中。将vexNum数组作为UFS的数据成员,用以记录以此下标为根的 集合的元素数,在unionSet并集时将两个集合的元素数归加和。通过这种算法使得不必写一个像原版那样的for循环,在并集结束后将所有顶点遍历找出最大值(由于这个for循环中遍历时对每个顶点都调用了findRoot函数去求根,会增加很多开销,这也是为什么改写了之后时间开销一下子节省了1/4的缘故)。
题目描述:
Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements.Mr Wang selected a room big enough to hold the boys.
The boy who are not been chosen has to leave the room immediately. There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. After Mr Wang's selection any two of them who are still in this room should be friends (direct or indirect),
or there is only one boy left. Given all the direct friend-pairs, you should decide the best way.
输入:
The first line of the input contains an integer n (0 ≤ n ≤ 100 000) - the number of direct friend-pairs. The following n lines each contains a pair of numbers A and B separated by a single space that suggests A and B are direct
friends. (A ≠ B, 1 ≤ A, B ≤ 10000000)
输出:
The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep.
样例输入:
样例输出:
原版:
改进版:
以下有两个版本。改进版是看完《机试指南》后启发,将统计集合元素数的操作封装进了unionSet函数中。将vexNum数组作为UFS的数据成员,用以记录以此下标为根的 集合的元素数,在unionSet并集时将两个集合的元素数归加和。通过这种算法使得不必写一个像原版那样的for循环,在并集结束后将所有顶点遍历找出最大值(由于这个for循环中遍历时对每个顶点都调用了findRoot函数去求根,会增加很多开销,这也是为什么改写了之后时间开销一下子节省了1/4的缘故)。
题目描述:
Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements.Mr Wang selected a room big enough to hold the boys.
The boy who are not been chosen has to leave the room immediately. There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. After Mr Wang's selection any two of them who are still in this room should be friends (direct or indirect),
or there is only one boy left. Given all the direct friend-pairs, you should decide the best way.
输入:
The first line of the input contains an integer n (0 ≤ n ≤ 100 000) - the number of direct friend-pairs. The following n lines each contains a pair of numbers A and B separated by a single space that suggests A and B are direct
friends. (A ≠ B, 1 ≤ A, B ≤ 10000000)
输出:
The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep.
样例输入:
4 1 2 3 4 5 6 1 6 4 1 2 3 4 5 6 7 8
样例输出:
4 2
原版:
#include <iostream> #define MAXSIZE 10000000 using namespace std; struct UFS{//UnionFindSet 从0开始 int elem[MAXSIZE]; int size; void initiate(int size){ this->size=size; for (int i=0;i<size;i++) elem[i]=-1; } int findRoot(int x){ if (elem[x]==-1) return x; else return elem[x]=findRoot(elem[x]); } void unionSet(int x,int y){ int xroot=findRoot(x),yroot=findRoot(y); if (xroot!=yroot)//if x and y are from different set elem[xroot]=yroot; //merge xset into yset } }; UFS ufs; int vexNum[10000000]; int main(){ int n; int a,b; int root; int mostSet,mostNum;// mostSet是目前最多顶点的集合的根的下标 mostNum是目前最多顶点集合的顶点数 while (cin>>n){//n vexes,m edges //initiate ufs.initiate(10000000); for (int i=0;i<ufs.size;i++){ vexNum[i]=0; } //input&&union for (int i=0;i<n;i++){ cin>>a>>b; a-=1;b-=1; ufs.unionSet(a,b); } //count mostSet=0; mostNum=vexNum[0]; for (int i=0;i<ufs.size;i++){ root=ufs.findRoot(i);//得到此顶点所在集合的根 vexNum[root]++; if (vexNum[root]>mostNum){ mostNum=vexNum[root]; mostSet=root; } } //output cout<<mostNum<<endl; } return true; }
改进版:
#include <iostream> #define MAXSIZE 10000000 using namespace std; struct UFS{//UnionFindSet 从0开始 int elem[MAXSIZE]; int vexNum[10000000]; int size; void initiate(int size){ this->size=size; for (int i=0;i<size;i++) elem[i]=-1; for (int i=0;i<size;i++) vexNum[i]=1; } int findRoot(int x){ if (elem[x]==-1) return x; else return elem[x]=findRoot(elem[x]); } void unionSet(int x,int y){ int xroot=findRoot(x),yroot=findRoot(y); if (xroot!=yroot){//if x and y are from different set elem[xroot]=yroot; //merge xset into yset vexNum[yroot]+=vexNum[xroot]; vexNum[xroot]=0; } } }; UFS ufs; int main(){ int n; int a,b; int root; int mostSet,mostNum;// mostSet是目前最多顶点的集合的根的下标 mostNum是目前最多顶点集合的顶点数 while (cin>>n){//n vexes,m edges //initiate ufs.initiate(10000000); //input&&union for (int i=0;i<n;i++){ cin>>a>>b; a-=1;b-=1; ufs.unionSet(a,b); } //count if(n==0) mostNum=1; else{//union完毕,此时并查集已定型 mostNum=ufs.vexNum[0]; for (int i=0;i<ufs.size;i++){ if (ufs.vexNum[i]>mostNum) mostNum=ufs.vexNum[i]; } } //output cout<<mostNum<<endl; } return true; }
相关文章推荐
- 九度 OJ 1444:More is better
- 【九度OJ】题目1444:More is better 解题报告
- HDU-1856-More is better(并查集 集合最值)
- hdu 1856 More is better 并查集找最大集合
- 【九度】题目1444:More is better
- HDU 1856 More is better(并查集判断集合元素个数)
- 九度 题目1444:More is better
- More is better——并查集求最大集合(王道)
- 九度 题目1444:More is better
- 九度考研机试教程 67-题目1444:More is better
- 九度 题目1444:More is better
- More is better(hdu 1856 计算并查集集合中元素个数最多的集合)
- hdu1856 More is better (并查集)
- HDU - 1856 More is better 并查集
- HDOJ 1856 More is better(并查集)
- hdu 1856 More is better 并查集(二)
- HDOJ 1856 More is better (并查集)
- More is better(找并查集最大中元素个数)
- Graph Theory NO.4 HDU_1856_More is better_并查集
- hdu 1856 More is better 并查集模板题