並查集(求朋友圈的個數)

2021-07-14 16:11:23 字數 1565 閱讀 2047

有如下題目:

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

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

最後請分析所寫**的時間、空間複雜度。

此題最簡單並且最高效的解法就是使用並查集

並查集定義:

並查集是一種樹型的資料結構,用於處理一些不相交集合的合併及查詢問題。常常在使用中以森林來表示。

開始時每個元素構成乙個單元素的集合,然後按一定規律將屬於同一組的元素所在的集合合併。

應用到此題時:

第一步: 有5個人,則開闢乙個 大小為6的整形陣列int set[6](0號小標沒用),將陣列初始化為-1。

第二步:合併屬於同乙個朋友圈的人。

假定乙個朋友圈有乙個領導者(相當於並查集的根),就是陣列的第乙個元素,如:1就是領導者,3是領導者。屬於同乙個朋友圈的人都要合併到領導者的名下。

先合併兩個集合到1下邊,將set[2]置為1

合併,1和3都是2的朋友,則1,2,3屬於同乙個朋友圈

合併

第三步:遍歷一遍陣列找到幾個小於0的值就表示有幾個朋友圈

**實現如下:時間複雜度,空間複雜度o(n)

#pragma once

#include

using

namespace

std;

class unionset

int getroot(int p)

return p;

}void unionfriends(int p1, int p2)

}int friends(int n, int m, int r[2])

//計算朋友圈個數

for (int i = 1; i < n + 1; i++) //跳過0號下標,沒有第0個人

return count;

}private:

int _set[6];

int _n;

};void test()

, , };

unionset us;

int ret = us.friends(n, m, r);

cout

<< ret << endl;

}

C 求朋友圈的個數 並查集方法

有n個同學,他們之間有些是朋友,有些不是。友誼 是可以傳遞的,例如a和b是朋友,b和c是朋友,那麼a與c也是朋友 朋友圈就是完成 友誼 傳遞後的一組朋友。給定n n的矩陣代表同學間是否是朋友,如果m i j 1代表第i個學生與第j個學生是朋友,否則不是。求朋友圈的個數。例如 input 1,1,0 ...

PAT 朋友圈(並查集)

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

5 9 朋友圈 (並查集)

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