種類並查集 多個並查集同時使用技巧

2021-09-11 07:30:11 字數 1160 閱讀 9137

原題

題解

並查集能維護連通性、傳遞性,通俗地說,親戚的親戚是親戚。然而當我們需要維護一些對立關係,比如 敵人的敵人是朋友 時,正常的並查集就很難滿足我們的需求。這時,種類並查集就誕生了。常見的做法是將原並查集擴大一倍規模,並劃分為兩個種類。在同個種類的並查集中合併,和原始的並查集沒什麼區別,仍然表達他們是朋友這個含義。考慮在不同種類的並查集中合併的意義,其實就表達 他們是敵人 這個含義了。按照並查集美妙的 傳遞性,我們就能具體知道某兩個元素到底是 敵人 還是 朋友 了。至於某個元素到底屬於兩個種類中的哪乙個,由於我們不清楚,因此兩個種類我們都試試。

在本題中,用3倍的並查積的存各種動物的關係,一倍存本身,二倍存獵物,三倍存天敵,唯一容易忽略的點就是:一的獵物的獵物就是一的天敵即這是乙個迴圈生態鏈。那麼我們每次只要維護三個並查積的關係就可以了。

#includeint fa[300005];

int n,k,ans;

inline int read()

//讀入優化

int find(int x)

//查詢

int unity(int x,int y)

//合併

int main()

// 不屬於該食物鏈顯然為假

if(z==1)

//如果1是2的天敵或獵物,顯然為謊言

unity(x,y); unity(x+n,y+n); unity(x+2*n,y+2*n);

//如果為真,那麼1的同類和2的同類,1的獵物是2的獵物,1的天敵是2的天敵

}else if(z==2)

//其實是廢話但是可以稍微省點時間

if(find(x)==find(y)||find(x+2*n)==find(y))

//如果1是2的同類或獵物,顯然為謊言

unity(x,y+2*n); unity(x+n,y); unity(x+2*n,y+n);

//如果為真,那麼1的同類是2的天敵,1的獵物是2的同類,1的天敵是2的獵物}}

並查集及種類並查集

b站 並查集int find root int x return x int hebing int x,int y return0 檢驗 include using namespace std const int n 100 const int m 200 int parent n deep n i...

種類並查集

先來經典題目poj 1182 其實我現在都不是很明白這個題是怎麼做的 這道題貌似是並查集和向量做的,其中的關係推斷現在不是很明白。只知道和根節點的關係有三種,一種是同類 rank x 0 一種是被根節點吃掉 rank x 1 一種是吃掉根基點 rank x 2 如果不是很明白這道題的話可以跳過這道題...

種類並查集

食物鏈 poj 1182 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。有人用兩種說法對這n個動物所構成的食物鏈關係進行描述 第一種說法是 1 x y 表示x和y...