資料結構和演算法 並查集

2021-10-08 12:35:13 字數 2035 閱讀 3943

朋友圈問題

並查集,顧名思義,主要功能是合併查詢,主要處理一些集合的合併問題。假設有n個元素,它們分別屬於一些集合,每個元素最多只能屬於乙個集合,每個集合都有乙個「祖先」,這些集合就構成乙個並查集。

並查集的表示方式很簡單,只需要乙個陣列v(陣列的大小是元素的個數),對每個元素iv[i]表示它的父節點或祖先節點(如果i本身是某個集合的祖先節點,則v[i]==i)。下圖的並查集包括4個集合,v=[0,1,2,2,2,5,5,5,5,5]

進一步地,陣列counts表示以每個元素為祖先的集合大小。以上圖為例,counts=[1,1,3,0,0,5,0,0,0,0]

通常初始化每個元素自成乙個集合,所有集合的大小都是1

class

unionfind

;

並查集主要有兩個方法:查詢和合併。

查詢並返回元素x的祖先節點。

int unionfind::

find

(int x)

return anc;

}

如果某2個元素不屬於同一集合,且需要合併它們,將小集合合併到大集合裡。

xy是它們各自所屬集合的祖先節點。

void unionfind::

merge

(int x,

int y)

班上有n名學生。其中有些人是朋友,有些則不是。他們的友誼具有是傳遞性。如果已知ab的朋友,bc的朋友,那麼我們可以認為a也是c的朋友。所謂的朋友圈,是指所有朋友的集合。

給定乙個n * n的矩陣m,表示班級中學生之間的朋友關係。如果m[i][j] = 1,表示已知第i個和j個學生互為朋友關係,否則為不知道。你必須輸出所有學生中的已知的朋友圈總數。

使用並查集的思路:

(1)開始時每個學生自成乙個集合。

(2)遍歷矩陣m,根據學生之間的關係及各自的祖先節點,判斷是否要合併集合(修改陣列vcounts)。由於矩陣m是對稱的,所以只需遍歷一半。

(3)最後,通過陣列vcounts統計集合的數量。

class

unionfind

counts = vector<

int>

(n,1);

v = vector<

int>

(n);

for(

int i =

0; i < n;

++i)

for(

int i =

0; i < n;

++i)}}

}int ans =0;

for(

int i =

0; i < n;

++i)

}return ans;

}private

: vector<

int> v;

vector<

int> counts;

};

資料結構 並查集

並查集,顧名思義,合併 查詢 集合 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。對於概念等等的這裡不再贅述,直接講解應用。應用1 判斷圖中有多少聯通分量 或者圖是否聯通 聯通分量 1 hdu 1213 應用2 判斷圖是否...

資料結構 並查集

time limit 1000ms memory limit 65536k 某城市有n個人,現在給定關於n個人的m條資訊,m條資訊是兩個人在同乙個小區,根據所給資訊,判斷這個城市最多可能有多少個小區。n個人編號為1 n。多組輸入。每組第一行有兩個整數n,m 2 n 50000,0 m n 2 接下來...

資料結構 並查集

一 基本概念 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。常常在使用中以森林來表示。集就是讓每個元素構成乙個單元素的集合,也就是按一定順序將屬於同一組的元素所在的集合合併。在一些有n個元素的集合應用問題中,通常是在開始時讓每個元素構成乙個單元素的...