P2024 [NOI2001]食物鏈(並查集)
阿新 • • 發佈:2018-12-08
題目描述
動物王國中有三類動物 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 句話有的是真
的,有的是假的。當一句話滿足下列三條之一時,這句話就是假話,否則就是真話。
• 當前的話與前面的某些真的話衝突,就是假話
• 當前的話中 X 或 Y 比 N 大,就是假話
• 當前的話表示 X 吃 X,就是假話
你的任務是根據給定的 N 和 K 句話,輸出假話的總數。
輸入輸出格式
輸入格式:
從 eat.in 中輸入資料
第一行兩個整數,N,K,表示有 N 個動物,K 句話。
第二行開始每行一句話(按照題目要求,見樣例)
輸出格式:
輸出到 eat.out 中
一行,一個整數,表示假話的總數。
#include<bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int n,k,d[100010*3],g,a,b,ans;//分為3類,1吃2,2吃3,3吃1 int f(int x){return d[x]==x?x:d[x]=f(d[x]);} int main(){ cin>>n>>k;//N 個動物,K 句話。 //第一種說法是“1 X Y”,表示 X 和 Y 是同類。 第二種說法是“2 X Y”,表示 X 吃 Y 。 for(int i=1;i<=n*3;i++)d[i]=i; for(int i=0;i<k;i++){ cin>>g>>a>>b; if(a>n||b>n){ ans++;//cout<<"月結"<<endl; continue; } if(g==1){ if(f(a+n)==f(b)||f(a)==f(b+n))ans++;//2和1在一類 else{//a和b在一類 int x=f(a),y=f(b); d[x]=y; x=f(a+n),y=f(b+n); d[x]=y; x=f(a+n+n),y=f(b+n+n); d[x]=y; } }else { if(f(a)==f(b)||f(a)==f(b+n))ans++;//a和b是一類 else{ int x=f(a+n),y=f(b);//1和2 d[x]=y; x=f(a+n+n),y=f(b+n);//3和2 d[x]=y; x=f(a),y=f(b+n+n);//1和3 d[x]=y; } } } cout<<ans; return 0; }