POJ 1182食物鏈(並查集經典題)

2021-10-09 12:44:00 字數 2745 閱讀 9081

題目描述

動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a**, 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

題目分析

這道題需要我們維護並查集的同時維護每種動物與其它動物的關係(同類,吃,被吃)。本題的難點也就是如何維護這個關係。

我們可以通過維護每個節點到其根節點的距離,進而來表示每個動物之間的關係。

設x與其根節點px。d[x]表示x到根節點的距離。

d[x]%3=0 //表示x與px是同類

d[x]%3=1 //表示px吃x

d[x]%3=2 //表示x吃px

這樣假設完之後,我們可以對其進行推廣:

對於位於同一集合中的任意兩點x、y,如果:

(d[x]-d[y])%3==0,則x與y是同類

(d[x]-d[y])%3==1,則x吃y

(d[x]-d[y])%3==2,則y吃x

然後我們再來看看上面三種不合法的情況。

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

與前面的真話發生衝突:即不符合上面推廣的三種情況。在操作時加乙個特判即可。

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

這個直接判斷即可,沒什麼可說的。

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

(d[x]-d[x])%3一定是等於0的,判斷也符合上述的推廣,利用推廣條件進行判斷即可。

這道題的最後乙個難點是d的維護。

d[x] //表示x到其父節點p[x]的權值

注:因為在操作前,所有節點都先要呼叫find()函式找到其根節點。通過路徑壓縮,x的父節點p[x]會變為根節點。即:d[x]在實際操作中可以表示x到其根節點的權值。

find()+路徑壓縮時維護d:因為遞迴呼叫+路徑壓縮,p[x]的父節點一定是根節點。所以d[p[x]]為父節點到根節點的權值,d[x]為x到父節點的權值。將x連線到根節點上,d[x]變為x到根節點的權值=原(d[p[x]]+d[x])。

合併時d的維護:將以pb為根的集合接到pa上,那麼我們只需要更新d[pb]的值即可。設a和b分別為pa和pb集合內的一點,dist(x)表示x到根節點的權值。

以a與b的關係是同類為例:

因為a和b是同類,因此:(dist(a)-dist(b))%3==0,即(d[a]-d[b]-d[pb])%3==0 => d[pb]=d[a]-d[b]。

**如下

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define pii pair

using

namespace std;

const

int n=

1e5+

5,inf=

0x3f3f3f3f

;int p[n]

,d[n]

;int

find

(int x)

//找到x的根節點+路徑壓縮優化

return p[x];}

intmain()

}else}}

}printf

("%d\n"

,ans)

;return0;

}

poj1182 食物鏈(經典並查集)

題意 中文題 思路 最詳細的題解 include include include include include include include include include include include include include using namespace std define ma...

POJ 1182 食物鏈 經典並查集

食物鏈 time limit 1000ms memory limit 10000k total submissions 57770 accepted 16890 description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n...

POJ 1182 食物鏈 並查集經典

思路 設r x 表示節點x與根結點的關係,px表示x的根結點。記錄每個節點與其父節點的關係,就能很方便知道每個節點以及和它的父節點的關係。struct nodea maxn 關係 0表示同類,1表示父節點吃子節點,2表示子節點吃父節點 現在給定節點x和y,它們的關係是rel,如何判斷這句話是真還是假...