吃瓜題2(虛擬分類並查集 啟發式合併)

2021-08-20 13:51:50 字數 690 閱讀 7512

題意:

與吃瓜題1題意一致,只是西瓜的種類從兩種變成了無數種。

題解:

在吃瓜題1裡,由於只有兩類西瓜,因此我們可以使用分類的方法來表示異同。而在這題中,由於種類數無窮,我們只有記錄每個節點的對立節點,在詢問x與y的關係時,我們查詢x的對立節點集合中是否出現y節點。

那麼如何記錄對立節點集呢?我們採用set

當兩個節點確定異種的時候,我們分別在set[x]和set[y]中新增y和x

當兩個節點確定同種的時候,我們將他們的set合併到一起。合併是要注重技巧的!每次,我們選擇較小的set,新增到較大的set中。因此,最壞情況其實就類似於乙個二叉樹的合併次數,大約為n次。

#include

#include

using

namespace

std;

const

int maxn = 1e6 + 5;

int pre[maxn];

setdiff[maxn];

int findset(int x)

void unionset(int x,int y)

}else

}}int main()

while(m--)

else

}else

}return

0;}

吃瓜題2(虛擬分類並查集 啟發式合併)

題意 與吃瓜題1題意一致,只是西瓜的種類從兩種變成了無數種。題解 在吃瓜題1裡,由於只有兩類西瓜,因此我們可以使用分類的方法來表示異同。而在這題中,由於種類數無窮,我們只有記錄每個節點的對立節點,在詢問x與y的關係時,我們查詢x的對立節點集合中是否出現y節點。那麼如何記錄對立節點集呢?我們採用set...

並查集的啟發式合併

在原來剛接觸並查集的時候,感覺確實很方便,也是認為並查集就那麼點東西,簡單方便,但是後來無意間發現了乙個並查集的啟發式合併,可以對並查集進行優化,它優化的理論是用乙個陣列來記錄每個節點的深度,每一次合併都把節點向深度 高度 大的節點上進行合併,從而對最後的 生成樹 深度進行了優化。受益匪淺,好長時間...

並查集 啟發式合併,路徑壓縮

一直沒想過自己寫的並查集的複雜度 看那一行 還挺竊喜 貼一下正版的啟發式合併,這樣複雜度就真正到了反阿克曼函式那什麼balabala 乙個優化是 把小的樹合併到大樹中,這樣會讓深度不太大。這個優化稱為啟發式合併。乙個優化是把沿途上所有結點的父親改成根。這一步是順便的,不增加時間複雜度,卻使得今後的操...