關於並查集擴充套件域問題的一些小思考

2021-10-17 03:28:40 字數 1145 閱讀 1802

poj1182 食物鏈

並查集的性質:並查集擅長維護許多具有傳遞性得關係

此處用擴充套件域做;

開三倍陣列,1-n為同類域(self),n+1-2n為捕食域(eat),2n+1-3n為敵人域(enemy),先上ac**

#include

#include

using

namespace std;

const

int max_n =

5e4+10;

int fa[

3*max_n]

;int

find

(int x)

void

merge

(int x,

int y)

}void

init

(int n)

intmain()

; cin >> n >> m;

init

(n);

while

(m--

)int x_self

, x_eat

, x_enemy

;int y_self

, y_eat

, y_enemy;if

(k ==1)

else

}else

else}}

cout << cnt;

return0;

}

思考:造並查集時,考慮到的可能的關係僅有「x可吃y」或「x與y同類」,為什麼不能只維護兩個域(兩個並查集)?如x吃y則將x的捕食域與y的同類域合併而要進行三次操作呢。

先看兩句話:

1.若"1 x y",表示x和y是同類 (題目描述)

2.若"1 x y",表示x和y是同類,且x是a類動物

顯然2的條件更強,所以對於2僅需進行一次操作,對於1,x可能是a,b,c三類的任何一種,故要進行三次合併操作

不然也就沒法體現並查集的傳遞性了

ps:編碼規範:

1引用和指標的符號應靠近型別名,

int* i;

char& ch;

2使用顯式型別轉化而不是隱式型別轉化 static_cast< int >()

3使用列表初始化 reason:不允許窄化

int a;

並查集的擴充套件域

核心思想 fa a 儲存與a同類的 fa a 1 n 儲存與a發生第一類關係的 fa a 2 n 儲存與a發生第二類關係的 fa a 3 n 儲存與a發生第三類關係的 分析將並查集中儲存節點關係的f陣列擴大2倍,1 n表示朋友,n 1 2 n表示敵人。那麼對於x,y,如果x和y是朋友,直接合併,如果...

並查集的一些理解

從最基本的並查集之後引申到帶權並查集 抽象出種類並查集 實際上都是維護乙個又乙個集合之間的關係 並查集主要寫兩個函式find和merge find函式可以寫成路徑壓縮 或者 按秩合併 或者兩個同時寫 但一般單獨的路徑壓縮就可以了 find函式需要注意的是在find函式內維護陣列 需要等回溯時再維護 ...

種類並查集的一些理解

之前暑假集訓的時候學了一下並查集,但是那個時候完全搞不懂種類並查集 帶權並查集 的路徑壓縮以及兩個節點關係的合併。現在有重新學習了一下,算是對種類並查集有了一些粗淺的理解了吧。關於路徑壓縮 int find int x 其實之前我就不是很懂,為什麼要設乙個temp儲存father x 的值,不應該像...