食物鏈
time limit:1000ms
memory limit:10000k
total submissions:44880
accepted:13083
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
只有乙個整數,表示假話的數目。
做這題之前先認識一下並查集的邊權關係,設r[x]表示x到其父親節點f[x]的邊權,0表示同類,1表示x吃f[x],2表示x被f[x]吃。
這題中的d=1表示同類,d=2表示x吃y,則在r中變為了d-1如上圖所示。則要求t,根據向量關係有:
t=((d-1)+r[y]-r[x])%3; t=(r[x]+r[y])%3;
以上二式是解決此題的關鍵,好好理解一下再結合以下**應該可以解決本題了。
ac**:
#include#includeusing namespace std;
int f[50010],rank[50010];
int find(int x)
int judge(int d,int x,int y)
void union(int d,int x,int y)
int main()
s=0;
while(k--)
if(!judge(d,x,y))
else
}cout<
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...
POJ 1182 帶權並查集
食物鏈 time limit 1000ms memory limit 10000k total submissions 89563 accepted 26905 description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n...