poj 1182 食物鏈 帶權並查集

2021-07-02 23:30:05 字數 1941 閱讀 7324

食物鏈

time limit:1000ms

memory limit:10000k

total submissions:50713

accepted:14818

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 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
題目要求一組資料。。。
《挑戰程式設計競賽》88頁詳解:對於每只動物建立3個元素i-a,i-b,i-c,並用這3 乘 n 個元素建立並查集。這個並查集維護如下資訊:
1,i-x 表示i屬於種類x 。
2,並查集裡的每一組表示組內所有元素代表的情況都同時發生或不發生。
例如,如果i-a和i-b在同乙個組裡,就表示如果i屬於種類a那麼j一定屬於種類b,如果j屬於種類b那麼i一定屬於種類a。因此,對於每一條資訊,只需要按照下面進行操作就可以了。
第一種:x和y屬於同類 合併x-a和y-a,x-b和y-b,x-c和y-c。
第二種:x吃y,合併x-a和y-b,x-b和y-c,x-c和y-a。
記著和合併前需要判斷是否矛盾,判斷方案有二個,分別對應上面兩個操作:
第乙個:需要判斷x-a和y-b,x-a和y-c 是否在同一組,若在同一組 則false 否則 合併。
第二個:需要判斷x-a和y-a,x-a和y-c 是否在同一組(矛盾的前提為a吃a,a吃c), 若在同一組 則false 否則合併。
**實現:
#include #include #define max 150000+10

using namespace std;

int set[max];//存在父節點

int ans;//記錄假話數目

int n, k;

void init()//初始化

int find(int p)

return p;

}void merge(int x, int y)

void search()

if(d == 1)//同一類

}else} }

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

}int main()

poj 1182 食物鏈 帶權並查集

這個題需要將動物分成3種,每次以y 0為物件,吃他的x為1,需要注意的是下一次碰到x cha函式遞迴更新與x有關的物件 include include include includeusing namespace std define n 50005 int father n num n int c...

poj1182食物鏈 帶權並查集

基本思路 帶權並查集 簡單的理解就是將有關係的點合併到乙個集合,記錄每個點到集合根節點的權重 include include include define max 50010 using namespace std int par max 記錄集合根節點 int offset max 記錄每個節點到...

POJ 1182 食物鏈(帶權並查集)

a,b,c三種動物,a吃b,b吃c,c吃a。有n個動物,他們編號為1 n。輸入 第一行n,k,分別表示動物個數,給出k句話 有真有假 接下來n行每行一句話,每句的格式為三個整數 d,x,y。x,y為動物編號,d為1時表示x,y是同類,d為2時表示x吃y。說明 假話有三種 1 當前的話與前面的某些真的...