poj 食物鏈 (種類並查集)

2021-08-17 22:43:09 字數 1772 閱讀 9966

種類並查集的經典題

**飄過的小牛

:   

關係域更新:

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

仔細再想想,rootx-x 

、x-y

、y-rooty

,是不是很像向量形式

?於是我們可以大膽的從向量入手:

tx       ty

x   ~    y

對於集合裡的任意兩個元素x,y

而言,它們之間必定存在著某種聯絡,因為並查集中的元素均是有聯絡的(這點是並查集的實質,要深刻理解),否則也不會被合併到當前集合中。

那麼我們就把這2

個元素之間的關係量轉化為乙個

偏移量(大牛不愧為大牛!~ym

)。 由上面可知:

x->y 偏移量0時 

x和y同類

x->y 偏移量1時 

x被y吃

x->y 偏移量2時 

x吃y 有了這個假設,我們就可以在並查集中完成任意兩個元素之間的關係轉換了。

不妨繼續假設,x

的當前集合根節點

rootx,y

的當前集合根節點

rooty

,x->y

的偏移值為d-1(題中給出的詢問已知條件)

(1)如果

rootx

和rooty

不相同,那麼我們把

rooty

合併到rootx

上,並且更新

relation

關係域的值(

注意:p[i].relation表示i

的根結點到

i的偏移量!!!!(向量方向性一定不能搞錯)

)此時 rootx->rooty = rootx->x + x->y + y->rooty

,這一步就是大牛獨創的

向量思維模式

上式進一步轉化為:rootx->rooty = (relation[x]+d-1+3-relation[y])%3 = relation[rooty]

,(模3

是保證偏移量取值始終在

[0,2]

間) (2)如果

rootx

和rooty相同(

即x和y

在已經在乙個集合中,不需要合併操作了,根結點相同

),那麼我們就驗證

x->y

之間的偏移量是否與題中給出的

d-1一致

此時 x->y = x->rootx + rootx->y

上式進一步轉化為:x->y = (3-relation[x]+relation[y])%3

,若一致則為真,否則為假。

#includeusing namespace std;

#define maxn 50005

int f[maxn],group[maxn];

int n,m;

void init()

} int find(int x)

int merge(int d,int x,int y)

else

}int main()

printf("%d\n",ans);

return 0;

}

POJ 食物鏈 種類並查集

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

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

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

食物鏈 種類並查集

推薦blog傳送門,超級詳細 做題思路 種類並查集,首先利用乙個陣列a來確定並查集關係,同時在建立乙個陣列b來表示某點與他們的boss點 根點 的關係。現規定 0 某點與他的根點為同類 1 某點與他的根點的關係為,根點種類的動物的可以吃掉該點種類的動物 2 某點與他的根點的關係為,該點種類的動物的可...