並查集的常用操作:
將兩個集合合併
詢問兩個元素是否在同乙個集合中
並查集在近乎o(1)的時間內完成以上兩個操作。
基本原理:每個集合用一棵樹表示。樹根的編號就是整個集合的編號,每個結點儲存它的父節點。用p[x]
表示x的父節點的編號。
問題1:如何判斷樹根? 答: if(p[x]==x),只有樹根px= =x,其他結點不存在p[x]= =x
問題2:如何求x的集合編號?答:while(p[x] != x) x=p[x];
一直往上走
問題3:如何合併兩個集合?答:假設px是x的集合的編號,py是y的集合編號,合併就是p[x] =py
。把一棵樹掛在另一棵樹上。
並查集的時間花費在問題2上,即求x的集合編號上,需要while往上找,和樹的高度成正比,時間是o(logn),其實這裡可以優化,對於這棵樹中的結點,只需要遍歷一次讓每個結點找到樹根,然後每個結點都指向樹根結點,下次來求集合編號就是o(1)的時間複雜度。這種優化稱為路徑壓縮。
找集合編號的**
以一道模板題為例:acwing836. 合併集合//返回x的祖宗節點,即集合編號
//帶有路徑壓縮優化
int find
(int x)
;//返回x的祖宗節點,即集合編號
//帶有路徑壓縮優化
int find
(int x)
int main()
}}
並查集板子
void init int getf int x return father x int getf int x return father x void unite int x,int y else hdu 1213 how many tables include using namespace s...
並查集 全家桶板子
前言 並查集是用來解決 朋友的朋友也是朋友 類的問題,其實寫三個函式就能解決大部分題 重點的三個函式 核心部分 int fa n void init int findfa int x void union int x,int y 找連通分支數 或者說是不同的圈子數 int cnt 0 for int...
hdu1213 並查集板子
並查集是一種支援合併與查詢的資料結構,在森林中進行操作,加上路徑壓縮,合併和查詢的時間複雜度幾乎都是常數。並查集最基礎的作用就是建立不同的點之間的所謂的 關係 並且查詢兩者是否有關係。並查集的乙個特點是向量型關係傳遞性,比如a b b c,則有a c,是不是特別像向量之間的傳遞?在很多時候並查集的應...