小公尺麵試題 朋友圈問題 並查集

2021-07-24 21:59:03 字數 1502 閱讀 3572

假如已知有n個人和m對好友關係(存於數字r)。如果兩個人是直接或間接的好友(好友的好友的好友...),則認為他們屬於同乙個朋友圈,請寫出程式求出這n個人裡一共有多少朋友圈。

例如:n=5,m=3,r=,,},表示有5個人,1和2是好友,2和3是好友,4和5是好友。則1,2,3屬於乙個朋友圈,4,5屬於另乙個朋友圈,結果為兩個朋友圈。

這道題有很多種解法,首先想到的就是定義乙個陣列,陣列元素也是陣列。使用stl庫,定義這樣的乙個結構:

vector> _v;
然後遍歷每對好友關係,如果陣列中有相同元素(好友),就在當前陣列中新增該好友,最後,遍歷最外層陣列元素個數就可以知道有多少個朋友圈了。

作為小公尺麵試題,它不僅要求正確性還有效率,上面給出的解法也能做出這道題,但是效率太低,所以,在這裡,我使用一種更高效,快捷的資料結構-----並查集。

並查集:

並查集是一種樹型的

資料結構

,用於處理一些不相交

集合(disjoint sets)的合併及查詢問題。常常在使用中以

森林來表示。集就是讓每個元素構成乙個單元素的集合,也就是按一定順序將屬於同一組的元素所在的集合合併。在一些有n個元素的集合應用問題中,通常是在開始時讓每個元素構成乙個單元素的集合,然後按一定順序將屬於同一組的元素所在的集合合併,其間要反覆查詢乙個元素在哪個集合中。

如圖所示:

查詢根:

int getroot(int root)

return root;

}

合併朋友圈(判斷x1與x2是否已經為好友關係,不是則並合併到所在朋友圈):

void union(int x1,int x2)

}

int count()

return count-1;//因為0號位置不用,但初始化時初始化為了-1,需要減去多算的這乙個

}

整體**:

#pragma once

#include using namespace std;

#include #include class unionset

return root;

} void union(int x1,int x2) }

bool find(int x1,int x2)

int count()

return count-1; }

protected:

//vectorv;

int* _unionset;

int _n;

};int friend(int n,int m,int r[2])

,,,};//n=總人數,m=多少對好友關係

cout<

並查集(小公尺麵試題求朋友圈的個數)

一 並查集的引入 以小公尺的這道題為例 並查集定義 並查集實際上是右乙個陣列實現的,這個陣列比較特殊,最開始將陣列的每乙個資料看成乙個單獨的集合,用 1表示。然後根據題目要求1和2可以合併,將第2個資料合併到1上時,array 1 array 2 array 2 1 陣列的array 1 儲存其與a...

PAT 朋友圈(並查集)

某學校有n個學生,形成m個俱樂部。每個俱樂部裡的學生有著一定相似的興趣愛好,形成乙個朋友圈。乙個學生可以同時屬於若干個不同的俱樂部。根據 我的朋友的朋友也是我的朋友 這個推論可以得出,如果a和b是朋友,且b和c是朋友,則a和c也是朋友。請編寫程式計算最大朋友圈中有多少人。輸入的第一行包含兩個正整數n...

5 9 朋友圈 (並查集)

某學校有n個學生,形成m個俱樂部。每個俱樂部裡的學生有著一定相似的興趣愛好,形成乙個朋友圈。乙個學生可以同時屬於若干個不同的俱樂部。根據 我的朋友的朋友也是我的朋友 這個推論可以得出,如果a和b是朋友,且b和c是朋友,則a和c也是朋友。請編寫程式計算最大朋友圈中有多少人。輸入的第一行包含兩個正整數n...