poj 1182 食物鏈 並查集

2021-07-06 03:50:51 字數 3367 閱讀 4538

食物鏈

time limit:1000ms

memory limit:10000k

total submissions:55072

accepted:16149

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
source

noi 01

汗,在網上搜尋,看了半天的帶權並查集,看不懂,看了學妹的**看懂了,

有n個動物,對於每個動物k,設food[k]=k+i,food[k+i]=k+2i;food[k+2*i]=i;這樣就構成了一條迴圈食物鏈。

一共有三種動物,如果知道了兩個動物是一種那麼可以合併(並查集基本操作),並將他們對應的 food(**食者)和(捕食者)

合併。**上有注釋,很容易看懂:

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#pragma comment(linker, "/stack:102400000,102400000")

#define pi 3.1415926535897932384626

#define eps 1e-10

#define sqr(x) ((x)*(x))

#define for0(i,n) for(int i=0 ;i<(n) ;i++)

#define for1(i,n) for(int i=1 ;i<=(n) ;i++)

#define ford(i,n) for(int i=(n) ;i>=0 ;i--)

#define lson num<<1,le,mid

#define rson num<<1|1,mid+1,ri

#define mid int mid=(le+ri)>>1

#define zero(x)((x>0? x:-x)<1e-15)

#define mk make_pair

#define _f first

#define _s second

using namespace std;

//const int inf= ;

typedef long long ll;

//const ll inf =1000000000000000;//1e15;

//ifstream fin("input.txt");

//ofstream fout("output.txt");

//freopen("a.in","r",stdin);

//freopen("a.out","w",stdout);

const int inf =0x3f3f3f3f;

const int maxn= 50000+20 ;

//const int maxm= ;

/*總結:

一共有n個動物,這裡虛擬出了2*n個,最後一共有3*n個,把每個動物x都虛擬出乙個相應的食物food[x]和捕食它的動物food[food[x]],

這樣對於x,虛擬本身出來的動物food[x]和food[food[x]]本身和x不產生矛盾,

會讓我們方便解題。

*/int pre[3*maxn],food[3*maxn];

int a[3],b[3];

int n,n,ans;//n動物種數、n虛擬的3*n種動物,ans 答案(假話數)

int find(int x)

void samegroup(bool same,int x,int y)//如果d==1

for(int i=0;i<3;i++)//如果兩者之前的食物鏈沒有合併過

}void different(bool same ,int x,int y)//如果d==2

//說x、y不是同種動物,但是x、y又一樣,是假話

if(same)//如果兩者之前的食物鏈合併過

for(int i=0;i<3;i++)

}void work()

//動物序號 > 大於動物個數,假話

a[0]=find(x);a[1]=find(food[a[0]] );a[2]=find(food[a[1]] );//取x所在食物鏈的****動物

b[0]=find(y);b[1]=find(food[b[0]] );b[2]=find(food[b[1]] );//取y所在食物鏈的****動物

bool same=false;

for(int j=0;j<3;j++)

}//如果same==1,那麼證明x、y所在的食物鏈已經合併過了,只需要判斷真假

if(rela==1) samegroup(same,x,y);//如果d==1

else different(same,x,y);//如果d==2

}void init()

}int main()

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

return 0;

}

POJ 1182 食物鏈 並查集

此題利用並查集解決。對於每只動物i建立3個元素i a,i b,i c,並用這3 n個元素建立並查集。1 i x表示 i屬於種類x 2 並查集你的每一組表示組內所有元素代表的情況同時發生或不發生。對於每一條資訊,只需要按照下列操作即可 1.第一種 x,y同類,合併x a和y a x b和y b x c...

POJ 1182 食物鏈 (並查集)

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

POJ 1182 食物鏈(並查集)

description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。有人用兩種說法對這n個動物所構成的食物鏈關係進行描述 第一種說法是 1 x y 表示x和y是...