一種特別的樹形結構 並查集

2021-10-04 17:19:02 字數 1715 閱讀 4267

並查集主要解決連線問題

並查集操作:find(i) 查詢父親結點

isconnected(p,q) 查詢是否相連,返回bool

unionelements(p,q)合併兩個結點

普通版本:無路徑壓縮,無優化

class unionfind

// 析構函式

~unionfind()

// 查詢過程, 查詢元素p所對應的集合編號

int find(int p)

// 檢視元素p和元素q是否所屬乙個集合

// o(h)複雜度, h為樹的高度

bool isconnected( int p , int q )

// 合併元素p和元素q所屬的集合

// o(h)複雜度, h為樹的高度

void unionelements(int p, int q)

};

分別是size優化和rank優化

rank優化雖然沒比size優化好多少,甚至不如。但在某些特地情況下很有效。

平時最好就使用rank優化

size優化

// 合併元素p和元素q所屬的集合

// o(h)複雜度, h為樹的高度

void unionelements(int p, int q)

else

}

rank優化
// 合併元素p和元素q所屬的集合

// o(h)複雜度, h為樹的高度

void unionelements(int p, int q)

else if( rank[qroot] < rank[proot])

else

}

路徑壓縮
// 查詢過程, 查詢元素p所對應的集合編號

// o(h)複雜度, h為樹的高度

int find(int p)

return p;

// path compression 2, 遞迴演算法 路徑壓縮的效果比上面好,但是會有遞迴上的花銷,推薦使用遞迴演算法

// if( p != parent[p] )

// parent[p] = find( parent[p] );

// return parent[p];

}

最後建議是使用rank優化+遞迴find

class unionfind

}// 析構函式

~unionfind()

// 查詢過程, 查詢元素p所對應的集合編號

// o(h)複雜度, h為樹的高度

int find(int p)

// 檢視元素p和元素q是否所屬乙個集合

// o(h)複雜度, h為樹的高度

bool isconnected( int p , int q )

// 合併元素p和元素q所屬的集合

// o(h)複雜度, h為樹的高度

void unionelements(int p, int q)

else if( rank[qroot] < rank[proot])

else

}};

並查集的操作,時間複雜度近乎是o(1)的。

並查集用在查詢網路中兩個節點是否相連,但如果要查詢具體路徑、最短路徑的話就要使用圖論的知識。

樹形結構 並查集 帶權並查集

定義 帶權並查集即是結點存有權值資訊的並查集。適用 當兩個元素之間的關係可以量化,並且關係可以合併時,可以使用帶權並查集來維護元素之間的關係。權值 帶權並查集每個元素的權通常描述其與並查集中祖先的關係,這種關係如何合併,路徑壓縮時就如何壓縮。與並查集的區別 帶權並查集可以推算集合內點的關係,而一般並...

教程 關於一種比較特別的線段樹寫法

這篇noip水平的blog主要是為了防止我afo後寫法失傳而寫的 大霧 博主平常寫線段樹的時候經常用一種結構體飛指標的寫法,這種寫法具有若干優勢 出錯會報re方便用gdb一類工具快速定位錯誤 平衡樹也可以用類似寫法,一秒定位板子錯誤 而且將線段樹函式中相對比較醜陋的部分引數隱式傳入,所以 可能 看上...

最小生成樹的一種解法(並查集)

使用 並查集 的kruskal演算法 struct edge 為方便排序,用結構體來儲存邊的關係 struct edge e 10 比m大1即可 int n,m int f 7 sum 0,count 0 並查集所用變數,f陣列比n大1即可 void quicksort int left,int r...