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 的值,不應該像...