POJ食物鏈(經典種類並查集)

2021-09-02 15:36:48 字數 1523 閱讀 4099

食物鏈

動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b, b吃c,c吃a。 

現有n個動物,以1-n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。 

有人用兩種說法對這n個動物所構成的食物鏈關係進行描述: 

第一種說法是"1 x y",表示x和y是同類。 

第二種說法是"2 x y",表示x吃y。 

此人對n個動物,用上述兩種說法,一句接一句地說出k句話,這k句話有的是真的,有的是假的。當一句話滿足下列三條之一時,這句話就是假話,否則就是真話。 

1) 當前的話與前面的某些真的話衝突,就是假話; 

2) 當前的話中x或y比n大,就是假話; 

3) 當前的話表示x吃x,就是假話。 

你的任務是根據給定的n(1 <= n <= 50,000)和k句話(0 <= k <= 100,000),輸出假話的總數。 

input

第一行是兩個整數n和k,以乙個空格分隔。 

以下k行每行是三個正整數 d,x,y,兩數之間用乙個空格隔開,其中d表示說法的種類。 

若d=1,則表示x和y是同類。 

若d=2,則表示x吃y。

output

只有乙個整數,表示假話的數目。

sample input

100 7

1 101 1 

2 1 2

2 2 3 

2 3 3 

1 1 3 

2 3 1 

1 5 5

sample output

思路:關於這道題我們運用到了一種特殊的技巧,動物的關係我們大概可以分為3種,動物本生,獵物,天敵,我們用三倍的並查集來維護這個關係,接下來的東西就看**,感覺用**來講解比較詳細,感覺寫的也算是中規中矩

// luogu-judger-enable-o2

#includeusing namespace std;

int father[150010];

int n, m;

//並查集模板

int findfather(int x)

return x;

}void union(int a, int b)

}int main() else if (a == 1)

union(b, c);//合併該類

union(b + n, c + n);//合併該類的獵物

union(b + 2 * n, c + 2 * n);//合併該類的天敵

} else if (a == 2)

union(b, c + 2 * n);//合併該類和他獵物的天敵(敵人的敵人就是朋友)

union(b + n, c);//合併的獵物和後者(因為後者也是他的獵物)

union(b + 2 * n, c + n);//合併該類的天敵和後者的獵物(因為是3者相互克制關係,稍微想想就明白了)}}

cout << ans << endl;

return 0;

}

poj 食物鏈 (種類並查集)

種類並查集的經典題 飄過的小牛 關係域更新 當然,這道題理解到這裡思路已經基本明確了,剩下的就是如何實現,在實現過程中,我們發現,更新關係域是乙個很頭疼的操作,網上各種分析都有,但是都是直接給出個公式,至於怎麼推出來的都是一筆帶過,讓我著實頭疼了很久,經過不斷的看discuss,終於明白了更新操作是...

POJ 食物鏈 種類並查集

time limit 1000ms memory limit 10000k 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。有人用兩種說法對這n個動物所構成的食物鏈關係...

POJ1182 食物鏈 種類並查集(經典)

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