這是用並查集維護每個點和根節點的關係
只要我們知道了每個點和根節點的關係,就可以知道每兩個點之間的關係
就和族譜乙個道理,簡單舉個例子
假設族譜裡最上面的那個人(根節點)是爺爺
然後a是爺爺(根節點)的兒子
b是爺爺(根節點)的孫子
那麼就可以知道a和b的關係,a和b是父子
大致就是這個意思
然後這一題如何確定每個點和根節點的關係呢
由於是三種動物迴圈被吃
那麼就用每個點到根節點的距離,來表示它和根節點的關係
我們說的這個距離,是這個點到根節點的真正的距離mod 3後的值,mod 3之後只會有3個值,0和1和2
如果某個點到根節點的距離mod 3是1的話,表示這個點可以吃根節點
如果某個點到根節點的距離mod 3是2的話,表示這個點可以被根節點吃
如果某個點到根節點的距離mod 3是0的話,表示這個點和根節點是同類
總結下來就是
mod 3 餘 1的點,就是所有可以吃根節點的點、
mod 3 餘 2的點,就是所有可以被根節點吃的點,也是所有可以吃mod 3 餘 1的點
mod 3 餘 0的點,就是所有和根節點同類的點,也是所有可以吃mod 3 餘 2的點
根節點可以看成到自己的距離是0,所以就有
餘0的吃餘2,餘2的吃餘1,餘1的吃餘0
所以就可以把本題中的所有集合歸為上面三大類
如果說x吃y,y就是0,x就是1
吃1的就是2,z吃x,z就是2
吃2的就是3,3 mod 3 = 0,也就是0
k吃z,那k就是0
總結下來就是用並查集維護每個點到根節點的距離
但是我們實際記錄
的是每個點到它的父節點的距離
在做路徑壓縮時,再進行更新
p儲存父節點,d是距離
6int find(int
x) 12
return
p[x];13}
14int
main()
20int res = 0; //
假話個數
21while (m--) else
else
if (px != py)
35 } else
else
if (px !=py) 42}
43}44}
45 cout << res <
46return0;
47 }
註解一:
當我們把?這個數填好之後,x和y是同類
那麼在mod 3的意義下,d[x] + ? = d[y]
並查集 食物鏈
noi2001,水題,但是我調了很久。食物鏈time limit 1000ms memory limit 10000k total submissions 27766 accepted 8066 description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃...
並查集 食物鏈
食物鏈 description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。有人用兩種說法對這n個動物所構成的食物鏈關係進行描述 第一種說法是 1 x y 表示...
並查集 食物鏈
動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。有人用兩種說法對這n個動物所構成的食物鏈關係進行描述 第一種說法是 1 x y 表示x和y是同類。第二種說法是 2 ...