2020-12-26 社交叢集
阿新 • • 發佈:2020-12-26
技術標籤:AC的題解分享
當你在社交網路平臺註冊時,一般總是被要求填寫你的個人興趣愛好,以便找到具有相同興趣愛好的潛在的朋友。一個“社交叢集”是指部分興趣愛好相同的人的集合。你需要找出所有的社交叢集。
輸入格式:
輸入在第一行給出一個正整數 N(≤1000),為社交網路平臺註冊的所有使用者的人數。於是這些人從 1 到 N 編號。隨後 N 行,每行按以下格式給出一個人的興趣愛好列表:
其中Ki(>0)是興趣愛好的個數,hi[j]是第j個興趣愛好的編號,為區間 [1, 1000] 內的整數。
輸出格式:
首先在一行中輸出不同的社交叢集的個數。隨後第二行按非增序輸出每個叢集中的人數。數字間以一個空格分隔,行末不得有多餘空格。
輸入樣例:
8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4
輸出樣例:
3
4 3 1
題解
並查集的題。設定兩個陣列,一個用來存為同一個社交群體的使用者,一個存愛好。
將愛好陣列 hobby 全部設定為 -1
然後每次遇到一個新的愛好,先看這個愛好對應的數值值是不是 -1
- 是 -1:說明這個愛好是第一次出現,之前沒有人有過相同的愛好,把 hobby 陣列中對應的值改為這個人的編號
- 不是 -1:說明有人有相同的愛好,將這兩個人的集合合併
最後排個序就可以了
#include <bits/stdc++.h>
using namespace std;
ostream &sp(ostream &output);
bool cmp(int a, int b)
{
return a > b;
}
int father[1010];
int hobby[1010];
int findFather(int x)
{
if (x == father[x])
return x;
return findFather(father[x]);
}
int main()
{
std::ios::sync_with_stdio(false);
// fill(hobby, hobby + 1010, -1);
for (int i = 0; i < 1010; ++i)
{
father[i] = i;
hobby[i] = -1;
}
int n;
cin >> n;
char colon;
for (int i = 0; i < n; ++i)
{
int habitsNum;
cin >> habitsNum;
cin >> colon;
for (int j = 0; j < habitsNum; ++j)
{
int hobbyID;
cin >> hobbyID;
if (hobby[hobbyID] == -1) //說明還沒有人和這個人有一樣的愛好
hobby[hobbyID] = i;
else
{
// 把有相同愛好的人合併到一個並查集中
int a = findFather(i);
int b = findFather(hobby[hobbyID]);
if(a != b)
{
father[a] = b;
}
}
}
}
int cnt = 0;
int ans[1010];
fill(ans, ans + 1010, 0);
for (int i = 0; i < n; ++i)
{
// cout << "findFather(i) = " << findFather(i) << endl;
if (i == findFather(i))
cnt++;
ans[findFather(i)]++;
}
sort(ans, ans + 1010,cmp);// sort(ans,ans+cnt,cmp) 只能過 2 個點
cout << cnt << endl;
for (int i = 0; i < cnt - 1; ++i)
cout << ans[i] << “ ”;
cout << ans[cnt - 1] << endl;
return 0;
}