有N我的,若是任意2我的的愛好有相同的(就是有交集),那麼這2我的就是屬於同一個社交網絡,要求輸出這N我的組成了幾個社交網絡,而且輸出每一個社交網絡的人數算法
此題考察的是並查集的使用(並查集主要用來處理 若干個節點,有些節點互相相連,有些節點沒有鏈接,如何判斷其中兩個節點是否相連這樣的問題),目前來看,使用並查集求解此題應該是最好的選擇,能夠使用構建人與人的關係圖,而後遍歷有多少個連通份量,每個連通份量有多少節點,可是這種方式實現起來過於複雜。數組
並查集主要由1個集合,2個操做所組成,集合就是father保存每個節點的父節點,2個操做分別是查詢節點x的父親節點和合並2個節點所在的集合。入下面代碼所示:網絡
int father[1005];// 每個節點的父親節點 // 查詢節點x的父親節點 int findFather(int x){ while(x!=father[x]){ x = father[x]; } return x;//father[x]==x的纔是根節點 } // 合併a和b節點所在的集合 void Union(int a,int b){ int fa = findFather(a); int fb = findFather(b); if(fa!=fb){ father[fa] = fb; } }
在此題中,咱們須要構建一我的與人之間相互關聯的社交網絡,媒介是每個人所擁有的愛好,那麼咱們使用$hobbyOwner$記錄每個愛好的全部者,這樣在輸入每個愛好的時候,若是當前愛好沒有全部者,將當前愛好標記爲本身所獨有,不然就將該愛好全部者和當前人合併到一個社交網絡。在每個社交網絡構建完成後,咱們須要統計社交網絡的個數和每個社交網絡的人數,咱們使用$roots(set集合)$保存每個社交網絡的根節點,其個數即爲社交網絡的個數,$cluster$保存每個社交網絡的人數,具體作法就是,須要遍歷每個人,找到其根節點$root$,而後添加進$roots$中,而且統計當前社交網絡的人數++cluster[root]
。最後對cluster進行排序輸出便可。測試
int cluster[1005];// 每個社交網絡的人數 unordered_set<int> roots;// 保存每個根節點 // 統計社交網絡的個數,也就是根節點的個數 for (int k = 1; k <= N; ++k) { int root = findFather(k); ++cluster[root]; roots.insert(root); }
#include <cstdio> #include <unordered_map> #include <unordered_set> #include <algorithm> using namespace std; int father[1005];// 每個節點的父親節點 unordered_map<int,int> hobbyOwner;//每個愛好的全部者 int cluster[1005];// 每個社交網絡的人數 // 初始化每個節點的父親 void init(){ for (int i = 1; i <= 1000; ++i) { father[i] = i; } } // 查詢節點x的父親節點 int findFather(int x){ while(x!=father[x]){ x = father[x]; } return x;//father[x]==x的纔是根節點 } // 合併a和b節點所在的集合 void Union(int a,int b){ int fa = findFather(a); int fb = findFather(b); if(fa!=fb){ father[fa] = fb; } } bool cmp(int a,int b){ return a>b; } int main() { init(); int N;// 節點個數 scanf("%d",&N); for (int i = 1; i <= N; ++i) { int K; scanf("%d: ",&K); for (int j = 0; j < K; ++j) { int hobby; scanf("%d",&hobby); if(hobbyOwner[hobby]==0){ // 當前愛好沒有人擁有 hobbyOwner[hobby] = i; } else { // 已經擁有了,合併擁有者和i Union(hobbyOwner[hobby],i); } } } unordered_set<int> roots;// 保存每個根節點 // 統計社交網絡的個數,也就是根節點的個數 for (int k = 1; k <= N; ++k) { int root = findFather(k); ++cluster[root]; roots.insert(root); } printf("%lu\n",roots.size()); sort(cluster+1,cluster+N+1,cmp); for(int i=1;i<=roots.size();++i){ printf("%d",cluster[i]); if(i<roots.size()) printf(" "); } return 0; }