[PAT] A1107 Social Clusters

tech2022-09-02  113

并查集

AC代码

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <cstdio> #include <vector> #include<algorithm> using namespace std; #define N 1002 int isRoot[N] = { 0 }, father[N]; vector<int>hobbies[N]; int findFather(int v) { int a = v; while (father[v] != v)v = father[v]; while (father[a] != v) { int z = father[a]; father[a] = v; a = z; } return v; } void merge(int a, int b) { int u = findFather(a); int v = findFather(b); if (u != v)father[u] = v; } bool ifmerge(int a, int b) { int flag = false; for (int i = 0;i < hobbies[a].size();i++) for (int j = 0;j < hobbies[b].size();j++) { if (hobbies[a][i] == hobbies[b][j])flag = true; } return flag; } bool cmp(int a, int b) { return a > b; } int main() { int n, i, j; scanf("%d", &n); int thobby, numhobby; for (i = 1;i <= n;i++) { scanf("%d: ", &numhobby); for (j = 0;j < numhobby;j++) { scanf("%d", &thobby); hobbies[i].push_back(thobby); } } for (i = 1;i <= n;i++) father[i] = i; for (i = 1;i < n;i++) { for (j = i + 1;j <= n;j++) { if(ifmerge(i, j)) merge(i, j); } } for (i = 1;i <= n;i++) isRoot[findFather(i)]++; int numcluster = 0; for (i = 1;i <= n;i++) if (isRoot[i] != 0)numcluster++; printf("%d\n", numcluster); sort(isRoot, isRoot + n + 1, cmp); if (isRoot[0] != 0)printf("%d", isRoot[0]); i = 1; while (isRoot[i] != 0) { printf(" %d", isRoot[i]); i++; } return 0; }

对比柳神的代码,发现爱好不需要用vector数组存起来,可以输入一个处理一个。即:

用course[t]表示任意一个喜欢t活动的人的编号。

如果当前的活动t之前没有人喜欢过(course[t]==0),那么就course[t] = i,i为它自己的编号,表示i为喜欢course[t]的一个人的编号。如果t之前有人喜欢过了,那么就让i和喜欢这个活动的人(即course[t])处在同一个社交圈里, 即Union(i, findFather(course[t]))。

代码实现如下:

for(int i = 1; i <= n; i++) { scanf("%d:", &k); for(int j = 0; j < k; j++) { scanf("%d", &t); if(course[t] == 0) course[t] = i; else Union(i, course[t]); } }
最新回复(0)