食物鏈 並查集

2021-08-21 17:25:23 字數 3079 閱讀 5620

動物王國中有三類動物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 7

1 101 1

2 1 2

2 2 3

2 3 3

1 1 3

2 3 1

1 5 5

sample output

3
(參考部落格,謝謝大佬,自己再次寫了一下自己的一點兒理解)

菜鳥分析:

有三類動物a,b,c,構成食物鏈:a吃b, b吃c,c吃a。

輸入:第一行是兩個整數n和k,以乙個空格分隔

以下k行每行是三個正整數 d,x,y,。

若d=1,則表示x和y是同類。

若d=2,則表示x吃y。

輸出:假話的數目

列三條之一時,這句話就是假話,否則就是真話。

1) 當前的話與前面的某些真的話衝突,就是假話;

2) 當前的話中x或y比n大,就是假話;

3) 當前的話表示x吃x,就是假話。

**:三個數字代表三種關係(x是乙個數字)

x表示x屬於a類,

x+n表示x屬於b類,

x+2*n表示x屬於c類

合併關係,就直接相當於合併數字

#include#includeusing namespace std;

int fa[150010];

int find(int x)//x的father為自身

return fa[x]=find(fa[x]);//不是自身繼續找

}//same函式 判斷x y是否是同乙個father,即是否同類,同類就為同乙個father

int same(int x, int y)

//bind函式將x y組合,即為同乙個father

void bind(int x, int y)//組合

int main()//初始化並查集

for(int j=1; j<=k; j++)

if(no==1)//錯誤情況

//1 x y 同類,如果是對的則以下三種情況

else//正確情況

} //2 x y,表示x吃y

else//錯誤情況

else//正確情況

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

return 0;

}

**補充說明:剛開始是代表a b c代表吃的順序,後來由於unite函式,a b c的關係從絕對關係由於unite函式變成了相對關係

若1 x y是錯誤的直接看是有same(x, y+n)或same(y+2*n, x),same這邊表示兩個元素在同乙個集合。

same(x, y+n)表示x可以吃y;同理same(y+2*n, x)表示y可以吃x;

因為unite的操作,一旦有x吃y,接著所有的情況也被包括了。

bind(x, y+n);//a吃b

bind(x+n, y+2*n);//b吃c

bind(x+2*n, y);//c吃a

所以same(x, y+n)其實同時也包含了same(x+n, y+2*n)以及

same(y+2*n, x);就是等於同時把所有情況也都舉了。

案例分析:

1.手動

100 7

1 101 1(x或y比n大,就是假話)❌     x>n ans++

2 1 2   (1吃2)                                       bind(1,2)

2 2 3 (2吃3)                                    bind(2,3)

2 3 3 (x吃x,就是假話)❌            same(3,3)  same(x,y)  ans++

1 1 3 (1 3同類)❌                          same(1,3)  same(x,y+2*n)  ans++

2 3 1 (3吃1符合食物鏈)                  bind(3,1)  適合食物鏈

1 5 5(5 5同類)                                bind(5,5)

所以假話3

不加注釋**:

#include#includeusing namespace std;

int fa[150010];

int find(int x)

return fa[x]=find(fa[x]);

}int same(int x, int y)

void bind(int x, int y)

for(int j=1; j<=k; j++)

if(no==1)

else

} else

else

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

return 0;

}

並查集 食物鏈

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 ...