基本步驟:初始化、不斷合併的過程中查詢、統計集合。
樹狀圖:
//初始化
intfind_set
(int x)
//查詢根節點
void
union_set
(int x,
int y)
//合併集合
intmain()
for(
int i=
1;i<=n;i++
)//有幾種不同的根
if(i==s[i]
) ans++
; cout << ans << endl;
}return0;
}由於查詢find_set()、合併union_set()正如上圖一樣,搜尋深度為o(n),n為樹的高度。可以分別對查詢與合併進行優化(樹的高度)。步驟:在合併x,y的時候先搜尋到他們的根節點,並合併這兩個根節點。
根據這兩個根節點的高度不同,把高度小的加到高度大的集合上。
利用陣列int height
來記錄高度
const
int maxn =
1005
;int s[maxn]
, height[maxn]
;void
init_set()
}void
union_set
(int x,
int y)
else
}
樹狀圖:
步驟:
搜尋的過程中,改變根節點。
優點:
優化了下一次的查詢,也優化了合併。
int
find_set
(int x)
int
find_set
(int x)
}
高階資料結構 並查集
優化路徑壓縮 o nlogn 按秩合併 o nlogn o n o 1 當n 161987 n 5維護 形成環兩個點在連邊之前在乙個集合中 二維 一維 x,y x n y x,y 都從0開始 acwing1252.搭配購買 01揹包 錢為容量 每個連通塊為乙個物品 總體積 總價值 繫結到根節點 p ...
資料結構之並查集
並查集 union find sets 是一種簡單的用途廣泛的集合.並查集是若干個不相交集合,能夠實現較快的合併和判斷元素所在集合的操作,應用很多,如其求無向圖的連通分量個數 最小公共祖先 帶限制的作業排序,還有最完美的應用 實現kruskar演算法求最小生成樹。其實,這一部分 演算法導論 講的很精...
資料結構之並查集
覺得很不錯的參考資料引用一下 陣列實現 合併操作代價高,可達o n 2 鍊錶實現 樹結構實現 查詢與合併的平均時間複雜度為o log 2 n 與樹的深度有關,優化 降低時間複雜度 按秩合併 若h b h b,則將b樹作為a樹的子樹。帶路徑壓縮的查詢演算法 改變結點所指方向以減小深度,查詢路徑時 走兩...