動物王國中有三類動物 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 句話有的是真
的,有的是假的。當一句話滿足下列三條之一時,這句話就是假話,否則就是真話。
• 當前的話與前面的某些真的話衝突,就是假話
• 當前的話中 x 或 y 比 n 大,就是假話
• 當前的話表示 x 吃 x,就是假話
你的任務是根據給定的 n 和 k 句話,輸出假話的總數。
輸入格式:
從 eat.in 中輸入資料
第一行兩個整數,n,k,表示有 n 個動物,k 句話。
第二行開始每行一句話(按照題目要求,見樣例)
輸出格式:
輸出到 eat.out 中
一行,乙個整數,表示假話的總數。
輸入樣例#1:
複製
100 71 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
輸出樣例#1:
複製
3
1 ≤ n ≤ 5 ∗ 10^4
1 ≤ k ≤ 10^5
***********************************====
emm......這題算是一種新題型吧,確實不看題解的話自己這種蒟蒻很難想到開3倍並查集的方法。
三倍的並查集,1~n表示動物間是否屬於同一類;n+1~2n表示乙個食物集合,即如果1吃2,則將1~n中的1與n+1~2n中的2相連;同理,2n+1~3n表示乙個天敵集合。
然後,對於每一句話的判斷,如果為「1」型別,需要判斷兩種動物間是否具有捕食關係。(因為後面對「a吃b,b吃c,c自然吃a」的特殊處理,所以在判斷捕食關係時均用1~n中元素作為捕食者,n+1~2n中元素作為食物);若為「2」型別,例如a吃b,則需要排除①a、b同類 ②b吃a 的情況,前者無疑在1~n的集合中判斷,而後者仍然要取1~n中元素作為捕食者,n+1~2n中元素作為食物。
另外,對於a吃b、b吃c、然後c自然吃a,所以連線c(1~n)、a(n+1~2n)的處理為什麼是連線a(n+1~2n),b(2n+1~3n),畫一下圖就可以看出來了,確實挺巧妙的。
所以綜上所述,在實現過程中,判斷是否同類是在集合1~n中進行,判斷捕食關係是在集合1~n和集合n+1~2n中進行。
最後,如果該句話錯誤,ans自然加一,但如果正確,對於「1」型別句子,需要合併集合對應兩個動物序號,且3部分集合中均需要合併,因為假設a在食物集合中有食物b,那麼食物集合中與b同類的動物d也要與捕食者a相連
;而對於「2」型別,若錯誤,ans++,反之正確,則集合1中捕食者與集合2中食物相連、集合1中食物與集合三中天敵相連、另外集合2中捕食者與集合3中食物相連(代表食物的食物是捕食者的天敵......畫下圖就好理解了)。
參考題解:
ac**:
#includeusing namespace std;
int fat[50001*3];
int father(int x)
void unionn(int x,int y)
int ans=0;
int main()}}
else if(flag==2)}}
}}
cout<
the end;
洛谷 P2024 食物鏈(並查集)
題意 有三種生物a,b,c,它們的關係是a吃b,b吃c,c吃a。現在給出一些語句,判斷是否是假話,輸出假話數量。輸入類似 a x y,如果a等於1,說明x,y是同類,a等於2說明x是y的天敵。思路 經典的並查集題目,用x表示生物本身,x n表示它的獵物,x 2 n表示它的敵人,具 體請看 注釋。如下...
洛谷 P2024 食物鏈
題目描述 動物王國中有三類動物 a,b,c,這三類動物的食物鏈構成了有趣的環形。a 吃 b,b 吃 c,c 吃 a。現有 n 個動物,以 1 n 編號。每個動物都是 a,b,c 中的一種,但是我們並不知道 它到底是哪一種。有人用兩種說法對這 n 個動物所構成的食物鏈關係進行描述 第一種說法是 1 x...
洛谷 P2024 食物鏈
題目描述 動物王國中有三類動物 a,b,c,這三類動物的食物鏈構成了有趣的環形。a 吃 b,b 吃 c,c 吃 a。現有 n 個動物,以 1 n 編號。每個動物都是 a,b,c 中的一種,但是我們並不知道 它到底是哪一種。有人用兩種說法對這 n 個動物所構成的食物鏈關係進行描述 第一種說法是 1 x...