AC日记——食物链 codevs 1047
1074 食物鏈
?2001年NOI全國(guó)競(jìng)賽
?時(shí)間限制: 3 s ?空間限制: 64000 KB ?題目等級(jí) : 鉆石 Diamond 題解 題目描述?Description動(dòng)物王國(guó)中有三類動(dòng)物 A,B,C,這三類動(dòng)物的食物鏈構(gòu)成了有趣的環(huán)形。A吃B,B吃C,C吃A。
現(xiàn)有N個(gè)動(dòng)物,以1-N編號(hào)。每個(gè)動(dòng)物都是A,B,C中的一種,但是我們并不知道它到底是哪一種。
有人用兩種說法對(duì)這N個(gè)動(dòng)物所構(gòu)成的食物鏈關(guān)系進(jìn)行描述:
第一種說法是“1 X Y”,表示X和Y是同類。
第二種說法是“2 X Y”,表示X吃Y。
此人對(duì)N個(gè)動(dòng)物,用上述兩種說法,一句接一句地說出K句話,這K句話有的是真的,有的是假的。當(dāng)一句話滿足下列三條之一時(shí),這句話就是假話,否則就是真話。
1) 當(dāng)前的話與前面的某些真的話沖突,就是假話;
2) 當(dāng)前的話中X或Y比N大,就是假話;
3) 當(dāng)前的話表示X吃X,就是假話。
你的任務(wù)是根據(jù)給定的N(1<=N<=50,000)和K句話(0<=K<=100,000),輸出假話的總數(shù)。
輸入描述?Input Description第一行是兩個(gè)整數(shù)N和K,以一個(gè)空格分隔。
以下K行每行是三個(gè)正整數(shù)D,X,Y,兩數(shù)之間用一個(gè)空格隔開,其中 D 表示說法的種類。
若D=1,則表示X和Y是同類。
若D=2,則表示X吃Y。
輸出描述?Output Description只有一個(gè)整數(shù),表示假話的數(shù)目。
樣例輸入?Sample Input100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
樣例輸出?Sample Output3
數(shù)據(jù)范圍及提示?Data Size & Hint輸入文件??
?對(duì)7句話的分析 100 7
1 101 1 假話
2 1 2 ? 真話
2 2 3 ? 真話
2 3 3 ? 假話
1 1 3 ? 假話
2 3 1 ? 真話
?1 5 5 ? 真話
NOI 2001 食物鏈(eat)
?
思路:
并查集;
怎么做呢?
有人說要用帶權(quán)并查集
然而我是蒟蒻我不會(huì)
我們要開三倍的n的father數(shù)組
i表示與i同類的集合
i+n表示i可以吃的集合
i+n+n表示i+n可以吃且可以吃i的集合
然后每次判斷是否是符合已有的真話
不符合ans++
符合就作為一條新的真話
?
來,上代碼:
#include <cstdio>#define maxn 50001 #define maxm 100001using namespace std;class Finding {private:int n,m,f[maxn*3],if_z,ans;char Cget;inline void read_int(int &now_){now_=0,if_z=1,Cget=getchar();while(Cget>'9'||Cget<'0'){if(Cget=='-') if_z=-1;Cget=getchar();}while(Cget>='0'&&Cget<='9'){now_=now_*10+Cget-'0';Cget=getchar();}now_*=if_z;}public:Finding(){read_int(n),read_int(m);for(int i=1;i<=n*3;i++) f[i]=i;int type,x,y;for(int i=1;i<=m;i++){read_int(type),read_int(x),read_int(y);if(x>n||y>n){ans++;continue;}if(type==1){if(If_same(x,y+n)||If_same(x,y+n+n)){ans++;continue;}else{Merge(x,y);Merge(x+n,y+n);Merge(x+n+n,y+n+n);}}else{if(If_same(x,y)||If_same(x+n+n,y)){ans++;continue;}else{Merge(x+n,y);Merge(x+n+n,y+n);Merge(x,y+n+n);}}}printf("%d\n",ans);}int Find(int x){if(x==f[x]) return x;f[x]=Find(f[x]);return f[x];}bool If_same(int x,int y){if(Find(x)==Find(y)) return true;else return false;}void Merge(int x,int y){x=Find(x),y=Find(y);if(x!=y) f[x]=y;} }; class Finding do_;int main() {return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/IUUUUUUUskyyy/p/6296597.html
總結(jié)
以上是生活随笔為你收集整理的AC日记——食物链 codevs 1047的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BZOJ 1568 李超线段树
- 下一篇: $NF和 NF的区别