將一些東西合併在乙個集合。
通常的應用就有
1、並的優化
2、查的優化
直接連邊,查詢的時候暴力往上跳。
由於本人弱,目前只知道按秩合併。
所謂秩,就是乙個值,在進行合併的時候,比較2個集合的秩,秩小的向秩大的合併。
這樣並查集的高度就是o(
log)
o (l
og
)的。
可以維護一些資訊。比如說size,並查集中點與點、邊與邊之間的資訊。
還可以撤銷合併的操作。(用棧維護一下就好了)
寫點偽**:
void merge(int x,int y)
void ctrl_z(int x,int y)
這是並查集的一種啟發式合併。
由於本人弱,目前只知道路徑壓縮。
有的時候我們只想知道兩個元素是否在乙個集合(或在哪個集合)
時間複雜度:o(
nαn)
o (n
αn
)寫點偽**:
void
get(int x)
有一棵樹,兩個操作。1標記乙個點。2詢問最近乙個打了標記的祖先。
一開始只有根節點有標記。
最近打了標記的祖先。
考慮一條鏈怎麼做。實際上給x~y之間的點z打標記,相當於將點分為2個集合。
所以倒過來做,就變成合併集合的操作了。
這題 按秩合併。
題解位址
n個點的樹,您將從樹中獲得m個節點對,形式為(a1,b1),(a2,b2),…(am,bm).
給每一條邊定向,使得每一對節點對存在一條從ai到bi或從bi到ai的路徑。
現在要求方案數,對10^9+7取mod即可。
維護點的資訊
任意兩個點,在樹上只有唯一一條路徑。
根據這個可以想到並查集。
將路徑(ai,bi)上的邊合併。
從深度大的向深度小的連邊。
合併的時候同時維護一下邊的資訊:定義「方向」表示x與fa[x]的連邊方向。
顯然,乙個集合內的所有邊的」方向」是相同的。
如果並查集樹上x集合的邊和y集合的邊的「方向」相同,那麼無解。
考慮並查集樹上有什麼資訊可以維護。
設f[x]表示邊x的並查集樹根到邊x的方向的情況。
有時候拿個陣列來表示約束條件。
並查集 帶權並查集 種類並查集 入門基礎題
include include include include include include include includetypedef long long ll using namespace std const int inf 0x3f3f3f3f const int maxn 2e5 10...
並查集簡單題
題目傳送 poj 1611 the suspects ac include include include include include include include include include include include include include include define l...
並查集 題1
問題描述 今天是ignatius的生日。他邀請很多朋友。現在是晚餐時間。ignatius想知道他至少需要多少張桌子。你必須注意到,並不是所有的朋友都認識對方,所有的朋友都不想留在陌生人身上。這個問題的乙個重要規則是,如果我告訴你a知道b,b知道c,這意味著a,b,c彼此認識,所以他們可以留在乙個表中...