用父親結點陣列實現並查集

2021-10-01 18:12:58 字數 1770 閱讀 3044

1 #include2 #include3 #include4

using

namespace

std;

5 typedef struct ufset *ufset;

6struct

ufset

7ufs;

11int s[100001],y[100001],d[10000

],add;

12int uffind(int

e,ufset u)

1319

while(j!=e)

2025

return

j;26}27

int ufunion(int i,int

j,ufset u)

2834

intmain()

3545

for(i=0;i)

4653}54

int t=0

; 55

for(i=1;i1;i++)

56 62}

63 sort(s,s+t);

64 add=k=0;65

for(i=1;;i++)

6674

}75 printf("

%d\n

",k);

76 sort(d,d+k);

77for(i=0;i)

7884

return0;

85 }

view code

並查集結構簡單。在資料結構作業大招秒殺和戰爭來了中有巧妙的運用

在下面所描述的改進的並查集結構中增加乙個根節點陣列root,用來記錄樹的根結點。

當元素e所在結點不是根節點時,root[e]=0,parent[e]=表示其父節點;當元素e所在結點是根節點

時,root[e]=1,parent[e]的值是樹中結點的個數.

1 typedef struct ufset *ufset;

2struct

ufset

3ufs;

uffind(e.u)運算從元素e相應的結點走到樹根處,找出所在集合的元素

加速並查集運算的另一的辦法就是採用路徑壓縮技術,在執行uffind時,實際是找到了從乙個結點

到樹根的一條路徑。路徑壓縮技術就是把這條路上的所有結點都改為樹根的兒子,實現路徑壓縮的最簡單方法是

在這條路上走兩次,第一次找到樹根,第二次將路上所有結點的父節點都改為樹根。

int uffind(int

e,ufset u)

while(j!=e)

return

j;}

在最壞情況下,合併可能使n個結點的數退化成一條鏈,在這種情下,對所有元素各執行

一次uffind將耗時o(n*n) 。所以,儘管,ufunion只需要o(1)時間,當uffind可能是總時間

耗費很大,為了克服這個缺點。可以做以下改進,使得每次ufind不超過o(longn)時間。在樹

根中儲存該樹的結點數,每次合併時,總將小樹合併到大樹上。當乙個結點從一棵樹移到另

一顆數上時,這個節點到樹根的距離就增加1,而這個節點所在的樹的大小至少增加一倍。

於是並查集中每乙個結點至多被移動o(longn)次,從而每個節點到樹根的距離不會超過o(longn)。

所以每次uffind運算只需要o(longn)時間。

int ufunion(int i,int

j,ufset u)

else

}

用c語言實現 並查集

題目描述 假如已知有n個人和m對好友關係 存於集合r 如果兩個人是直接或間接的好友 好友的好友的好友 則認為他們屬於同乙個朋友圈。請寫程式求出這n個人裡一共有多少個朋友圈。輸入輸入包含多個測試用例,每個測試用例的第一行包含兩個正整數 n m,1 n,m 100000。接下來有m行,每行分別輸入兩個人...

java實現並查集

並查集是根據這篇博文學習的,寫得很不錯 下面是實現 public class unionfindset count n 合併p,q所在集合 param p param q public void union int p,int q if size rootp size rootq else coun...

C 實現並查集

將n個不同的元素分成一組不相交的集合。開始時,每個元素就是乙個集合,然後按規律將兩個集合進行合併。假如已知有n個人和m對好友關係 存於陣列r 如果兩個人是直接的或間接的好友關係 好友的好友的好友.則認為他們屬於同一好友圈,請求出這n個人中有幾個好友圈。例如 n 5,m 3,r 表示有5個人,1和2是...