并查集--PAT.A1107.Social Clusters
来源:互联网 发布:最全的外文数据库 编辑:程序博客网 时间:2024/05/17 06:58
【2017/2/26】
【还有三个测试点不过!!!】【后附正确解法】
/******************3stone*****************************FileName: PAT.A1107.social clusterAuthor:3stoneTime:2017/3/7题意:N个人,每人有不同的爱好,统计有同类爱好的人,并输出人数人数[1,1000] 爱好类型[1,1000] 两个人有一个爱好相同则抽象为一条边用course[h]记录任意一个喜欢h活动的 人的编号作为根节点 findRoot(course[h])找到根节点对当前的人,对他的每一个爱好i,都要合并i 与 findRoot(course[h])还是以学生的编号进行并查集搜索*****************3stone*****************************/#include<cstdio>#include<algorithm>#define maxSize 10010using namespace std;int course[maxSize]; //喜欢 i 课程的任意一学生编号-作为根节点 int tree[maxSize]; //根节点int cluster[maxSize] = { 0 }; //每个群中的人数bool cmp(int a, int b) { return a > b;}int findRoot(int x) {//寻根 if (-1 == tree[x]) return x; else { int temp = findRoot(tree[x]); tree[x] = temp;//状态压缩 return temp; }}int main() { int n;//人数 while (scanf("%d", &n) != EOF) { for (int i = 1; i <= maxSize; i++) {//初始化 tree[i] = -1; course[i] = -1; cluster[i] = 0; } for (int i = 1; i <= n; i++) {//输入[注:是n-1行] int myNum, hNum; scanf("%d:", &myNum); for (int j = 1; j <= myNum; j++) { scanf("%d", &hNum); if (-1 == course[hNum]) {//此爱好 第一次出现 course[hNum] = i; //记录用户的编号 } else { int myRoot = findRoot(course[hNum]);//此爱好 对应的 根用户编号 if (tree[i] != myRoot) { tree[i] = myRoot; //合并集合 } } //printf("hNum: %d\n", hNum); }//for-j }//for-i/* // 为什么不能给tree[]排序,是要一加sort()就弹错 sort(tree + 1, tree + n + 2, cmp); printf("tree: %d", tree[1]); for (int i = 2; i <= n; i++) printf(" %d", tree[i]); printf("\ntree over\n");*/ int sum = 0; for (int i = 1; i <= n; i++) { if (tree[i] == -1) { sum++; //群的个数 cluster[i] = 1; } else { cluster[findRoot(tree[i])]++; } } sort(cluster + 1, cluster + n + 1, cmp);//小心序号 printf("%d\n", sum); printf("%d", cluster[1]); for (int i = 2; i <= sum; i++) printf(" %d", cluster[i]); printf("\n"); }//while return 0;}
【以下正确解法 转自《算法笔记》并查集】
#include<cstdio>#include<cmath>#include<algorithm>#define maxSize 1010using namespace std;int father[maxSize];int course[maxSize] = {0};int isRoot[maxSize] = {0}; //记录每个集合的元素个数 void init(int n){//初始化 for(int i = 1; i <= n; i ++){ father[i] = -1; isRoot[i] = false; }}int findF(int x){//寻找根节点 if(-1 == father[x]) return x; else{ int temp = findF(father[x]); father[x] = temp;//状态压缩 return temp; } }void Union(int a, int b){//合并集合 int ta = findF(a); int tb = findF(b); if(ta != tb) father[ta] = tb;}bool cmp(int a, int b){ return a > b;}int main(){ int n, k, h; while(scanf("%d", &n) != EOF){ init(n); for(int i = 1; i <= n; i++){ scanf("%d:", &k); for(int j = 1; j <= k; j++){ scanf("%d", &h); if(0 == course[h]){ course[h] = i; } Union(i, findF(course[h]));//爱好相同,合并集合 } } for(int i = 1; i <= n; i++){//统计人数 isRoot[findF(i)]++; } int ans = 0; for(int i = 1; i <= n; i++){ if(isRoot[i] != 0) ans++; } printf("%d\n", ans); sort(isRoot+1, isRoot + n + 1, cmp);//不能在[1-ans]排,不能保证根全 for(int i = 1; i < ans;i++) printf("%d ", isRoot[i]); printf("%d\n", isRoot[ans]); }//while return 0;}
0 0
- 并查集--PAT.A1107.Social Clusters
- PAT A1107. Social Clusters (30)
- PAT A1107 social clusters (30)
- PAT A1107. Social Clusters (30)
- PAT - 甲级 - 1107. Social Clusters (30) (并查集)
- PAT 1107. Social Clusters (30) 并查集
- A1107. Social Clusters (30)
- PAT 1107. Social Clusters (30) 特殊问题+并查集+数量信息并查集
- 1107. Social Clusters (30) 并查集
- 1107. Social Clusters (并查集 )
- 1107. Social Clusters (30)[并查集]
- 1107. Social Clusters (30) 并查集
- 1107. Social Clusters (30)并查集
- PAT (Advanced Level) Practise 1107. Social Clusters (30) 并查集
- PAT程序设计考题——甲级1107( Social clusters并查集) C++实现
- 【PAT】1107. Social Clusters
- PAT 1107 Social Clusters
- PAT 1107. Social Clusters
- Java NIO概述
- [软件测试]
- Linux入门级需要掌握的命令
- Google ZXing系列讲解(三)——ZXing 目录结构与主体流程
- javaweb接受跨域请求设置
- 并查集--PAT.A1107.Social Clusters
- 用jQuery实现菜单隐藏
- oj2494: 大写字母转小写字母
- synchronized同步方法
- CSS3基础——CSS 概述、语法
- 搭建自己的Django应用(3)Writing your first Django app, part 3
- java安全架构____java DSA加密解密
- codeforce 777 C. Alyona and Spreadsheet (线段树)
- hadoop中namenode工作机制简图