洛谷 P2024 食物链
题目分析:
就是用并查集判断一下。不过有个细节得注意下,就是本题中是说a吃b,b吃c,c吃a,那么可以总结为a的猎物的猎物是他的天敌。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,ans;
int fa[300000];
inline int read(){
int x=0,w=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
return x*w;
}
inline int gf(int x){
int u=x,c;
while(x!=fa[x]) x=fa[x];
while(u!=x) { c=fa[u]; fa[u]=x; u=c; }
return x;
}
/*inline int gf(int x){ return x==fa[x]?x:fa[x]=gf(fa[x]); }*/
inline void union1(int a,int b){
int f1=gf(a),f2=gf(b);
if(f1!=f2) fa[f1]=f2;
}
int main(){
n=read();m=read();
for(register int i=1;i<=3*n;++i) fa[i]=i;
for(register int i=1;i<=m;++i) {
int k=read(),u=read(),v=read();
if(u>n||v>n) {++ans;continue;}
if(k==1) {
if(gf(u+n)==gf(v)||gf(u+2*n)==gf(v)) {++ans;continue;}
//如果1是2的天敌或猎物,显然为谎言
union1(u,v);union1(u+n,v+n);union1(u+2*n,v+2*n);
//如果为真,那么1的同类和2的同类,1的猎物是2的猎物,1的天敌是2的天敌
}
else if(k==2) {
if(u==v) { ++ans;continue; }
if(gf(u)==gf(v)||gf(u+2*n)==gf(v)) {++ans;continue;}
//如果1是2的同类或猎物,显然为谎言
union1(u,v+2*n);union1(u+n,v);union1(u+2*n,v+n);
//如果为真,那么1的同类是2的天敌,1的猎物是2的同类,1的天敌是2的猎物
}
}
printf("%d",ans);
return 0;
}
422

被折叠的 条评论
为什么被折叠?



