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