食物鏈
time limit:1000ms
memory limit:10000k
total submissions:89563
accepted:26905
description
動物王國中有三類動物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 7sample output1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
3source
noi 01
這題我們怎麼看呢 可以通過列關係得到並查集查詢的時候的關係式
然後用某大牛的向量方法 得出答案 這也太巧妙了吧
由上面可知:
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,
若一致則為真,否則為假。
#include #include #include #include #include using namespace std;
const int max_n = 50024;
int father[max_n],rank_[max_n];
int find(int x)
int y = father[x];
father[x] = find(y);
rank_[x] = (rank_[x]+rank_[y])%3;
return father[x];
}int main()
while(k--)
if(q==2&&a==b)
int fa = find(a);
int fb = find(b);
if(fa!=fb)
else
}else if(q==2)}}
}printf("%d\n",ans);
return 0;
}
poj 1182 帶權並查集
description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。有人用兩種說法對這n個動物所構成的食物鏈關係進行描述 第一種說法是 1 x y 表示x和y是...
poj1182 帶權並查集
題意 中文題就不描述了 思路 帶權並查集模板題 加入乙個陣列 表示這個點和它父節點的關係 表示同類,表示父親吃它,表示它吃父親 每次需要更新和父親之間的關係 include includeconst int n 50005 int p n r n n,k void init int x int fi...
poj1182 帶權並查集
題意 一共有abc三種動物,a吃b,b吃c,c吃a,現在共有n個動物,編號1 n,給出k句話,判斷真假 每句話包含val,u,v val 1,代表u,v,是同類,val 2代表u吃v 假的條件為 1.與前面某些真話衝突 2.u,v,大於n 3.當val 2時,u v,即不能自己吃自己 思路 有聯絡的...