資料結構 帶權並查集

2022-01-10 12:56:50 字數 2511 閱讀 5394

顧名思義,就是在維護集合關係的樹中新增邊權的並查集,這樣做可以維護更多的資訊。

引入題目:

比如這道題,如果使用普通的並查集則無法處理,因為普通的並查集只能夠刻畫兩個物品是否屬於同乙個集合。因此這時候就要使用能夠記錄更多資訊的帶權並查集

在閱讀前,需要先掌握並查集的知識。

結合題目講解:

對於乙個物種(一類動物),如果存在它吃另乙個物種的關係,則讓它的度數比另乙個物種多 \(1\) 。更嚴格地說,我們記該物種為a(並非題意中的a),另乙個物種是b,它們對應的度數為d,那麼有 \(d[a]=d[b]+1\) 。如圖:

那麼有了這樣的規定,便有如下性質:

從上面的性質可以看出,兩個物種的關係與它們的模數(這題是 \(mod3\) )餘多少關係密切相關,因此接下來我們也會著重考察兩個數之間的這種關係。

利用度數以及並查集,即可將各種動物之間的關係刻畫清楚:

這裡依然對ab進行討論,為了方便,我們記a的祖宗(根節點)為pab的祖宗(根節點)為pb

綜上,我們的討論將所有情況覆蓋了。

路徑壓縮:

根據並查集的性質,如果不進行路徑壓縮,時間複雜度將會退化到 \(o(n)\) 。因此帶權並查集也要進行路徑壓縮,那麼主要問題就是解決如何維護d(度數)的問題:

概括地說,就是在查詢到某個點的時候,在搜尋它的祖宗時遞迴地求出路上所有結點的度數,那麼它的度數就是d[x]+=d[f[x]]

如上圖,pa在一次操作中併入了pb

而在另一次操作中,對a的進行了查詢(求祖宗),便有如下路徑壓縮的並更新d的過程:

遞迴地找出祖宗pb

pa的祖宗就是pb,度數在合併的時候已經求出來了,所以更新 \(0\)。

c的父親節點是pa,合併的時候並沒有更新(因此記錄的是距離pa的度數),度數需要加上 \(d[pa]\),然後進行路徑壓縮。

a的父親節點是c,在上一步更新了,所以度數加上 \(d[c]\) 即可,類似的,進行路徑壓縮。

(這裡可能有點難理解,不過只要記住:所謂的d[x]指的是節點x相對於它父節點的度數即可)

不理解的地方可以結合**理解

放上**:(很短的)

#includeusing namespace std;

const int n=5e4+5;

int f[n],d[n];

int find(int x)

return f[x];

}int main()

if(a==b && op==2)

int pa=find(a),pb=find(b);

int t= op==2;

if(pa==pb)else

}cout

分析:思路完全類似於食物鏈那題。

**#includeusing namespace std;

const int n=2e4+5;

unordered_maph;

int n,m;

int f[n];

int d[n];

int get(int x)

int find(int x)

return f[x];

}int main()

}else

}cout

資料結構 帶權 種類並查集

給出乙個區間的長度 n,及 m 個子區間和,形如 x y z,表示 子區間 x,y 的和為 z 如果乙個 子區間和 與前面的 子區間和 衝突,即為錯誤 而且這個 子區間和 將在接下來的判斷中被忽略 求總錯誤個數。帶權並查集 include include include using namespac...

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

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

並查集,帶權並查集

題意 ignatius過生日,客人來到,他想知道他需要準備多少張桌子。然而一張桌子上面只能坐上相互熟悉的人,其中熟悉可定義成為a與b認識,b與c認識,我們就說a,b,c相互熟悉 例如a與b熟悉and b與c熟悉,d與e熟悉,此時至少需要兩張桌子。輸入 t表示樣例個數,n表示朋友個數,朋友從1到n編號...