1. 程式人生 > 其它 >2020-12-26 社交叢集

2020-12-26 社交叢集

技術標籤:AC的題解分享

當你在社交網路平臺註冊時,一般總是被要求填寫你的個人興趣愛好,以便找到具有相同興趣愛好的潛在的朋友。一個“社交叢集”是指部分興趣愛好相同的人的集合。你需要找出所有的社交叢集。

輸入格式:

輸入在第一行給出一個正整數 N(≤1000),為社交網路平臺註冊的所有使用者的人數。於是這些人從 1 到 N 編號。隨後 N 行,每行按以下格式給出一個人的興趣愛好列表:

image-20201226001038537

其中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; }