1. 程式人生 > >[leetcode] 並查集(Ⅰ)

[leetcode] 並查集(Ⅰ)

## 預備知識 並查集 (Union Set) 一種常見的應用是計算一個圖中連通分量的個數。比如: ```text a e / \ | b c f | | d g ``` 上圖的連通分量的個數為 2 。 並查集的主要思想是在每個連通分量的集合中,選取一個代表,作為這個連通分量的根。根的選取是任意的,因為連通分量集合中每個元素都是等價的。我們只需關心根的個數(也是連通分量的個數)。例如: ``` text a e / | \ / \ b c d f g ``` 也就是說:`root[b] = root[c] = root[d] = a` 而 `root[a] = -1`(根節點的特徵也可以定義為 `root[x] = x`)。 最後計算 `root[x] == -1` 的個數即可,這也就是連通分量的個數。虛擬碼如下: ```cpp // n nodes, all nodes is independent at the beginning vector root(n, -1); int find(int x) { return root[x] == -1 ? x : (root[x] = find(root[x])); } // if x and y are connected, then call union(x, y) void unionSet(int x, int y) { x = find(x), y = find(y); if (x != y) root[x] = y; // it also can be root[y] = x } int main() { // (x,y) are connected while (cin >> x >> y) unionSet(x, y); // print the number of connectivity components print(count(root.begin(), root.end(), -1)); } ``` `find` 函式也可以通過迭代實現: ```cpp int find(int x) { int t = -1, p = x; while (root[p] != -1) p = root[p]; while (x != p) {t = root[x]; root[x] = p; x = t;} return p; } ``` ## 朋友圈 題目[547]:點選 [