一.定義
實現:int father[n];
father[i] = j; 表示 j 的父親結點是 i;father[i] = i; 表示元素 i 是該集合的根結點;
二.基本操作
1.初始化
for
(int i =
1; i <= n; i++
) father[i]
= i;
2.查詢
非遞迴實現:
int
findfather
(int x)
遞迴實現:
int
findfather
(int x)
3.合併
給出元素 a、b,把兩個元素所在的集合合併,思路:把其中乙個集合的根結點的父親指向另乙個集合的根結點;(合併產生的每乙個集合都是一棵樹)
void
union
(int a,
int b)
三.路徑壓縮
把當前查詢結點的路徑上的所有結點的父親都指向根結點,查詢複雜度可以降為 o(1);
1.非遞迴寫法:
int
findfather
(int x)
return x;
}
2.遞迴寫法:
int
findfather
(int v)
}
四.題目
1.好朋友
思路:
這種關係就是並查集的關係,乙個好朋友集合就是乙個並查集,用 union函式構造並查集;
計算並查集數:每個結點都找到根結點,利用乙個 bool 陣列標記;
注意:標號從1開始;
**:
#include
using
namespace std;
const
int maxn =
110;
int n, m;
int fred[maxn]
;bool flag[maxn]
;void
init()
}int
findfriend
(int a)
void
union
(int a,
int b)
intmain()
for(
int i =
1; i <= n; i++
) flag[
findfriend
(i)]
=true
;int ans =0;
for(
int i =
1; i <= n; i++
)printf
("%d"
, ans)
;return0;
}
2.pat a1107
思路:如何合併:合併的條件是有相同 hobby,所以可以列出乙個陣列 course[hobby] ,內容是有此 hobby 的人的編號。每次讀入某人的 hobby 時,將此人與 course[hobby] 的 father 合併(father 是第乙個有此 hobby 的人);
如何計算共有多少並查集+每個並查集的人數:
for
(int i =
1; i <= n; i++
)for
(int i =
1; i <= n; i++
)
**:
#include
#include
#include
using
namespace std;
const
int maxn =
1010
;int n, ans =0;
int course[maxn]=;
int isroot[maxn]=;
int father[maxn]
;void
init()
}int
findfather
(int x)
return x;
}void
union
(int a,
int b)
bool
cmp(
int a,
int b)
intmain()
}for
(int i =
1; i <= n; i++
)for
(int i =
1; i <= n; i++
)printf
("%d\n"
, ans)
;sort
(isroot +
1, isroot + n +
1, cmp)
;for
(int i =
1; i <= ans; i++
)return0;
}
演算法筆記練習 9 6 並查集 問題 A 通訊系統
本題鏈結 題目描述 某市計畫建設乙個通訊系統。按照規劃,這個系統包含若干端點,這些端點由通訊線纜鏈結。訊息可以在任何乙個端點產生,並且只能通過線纜傳送。每個端點接收訊息後會將訊息傳送到與其相連的端點,除了那個訊息傳送過來的端點。如果某個端點是產生訊息的端點,那麼訊息將被傳送到與其相連的每乙個端點。為...
演算法筆記 並查集
專題 並查集 一 引入 在一些有n個元素的集合應用問題中,我們通常是在開始時讓每個元素構成乙個單元素的集合,然後按一定順序將屬於同一組的元素所在的集合合併,其間要反覆查詢乙個元素在哪哪個集合中。該問題看似並不複雜,但資料量極大,若用正常的資料結構來描述的話,往往超過了空間的限制,計算機無法承受 而且...
並查集演算法筆記
並查集是一種用來管理元素分組情況的資料結構,並查集可以高效的進行如下操作 使用樹狀結構來實現 在樹形資料結構中,如果發生了退化的情況,複雜度就會變得很高。在並查集中,可以按照如下方法避免退化 並查集複雜度平均下來每次查詢和合併的複雜度都是常數的 阿克曼函式 leetcode 547.friend c...