【NOI2001】【Vijos1531】食物链
2018-03-25 10:40
423 查看
//本题思路:把x作为a,b,c三种动物分别加入,维护三个集合的关系。 //并查集及补集 //其中i用来连接与i同类的,i+n用来连接能吃i的,i+2*n用来连接i能吃的。 //具体来说,凡是与i+n节点在同一个集合里的,都是被i吃的动物。 #include<iostream> #include<algorithm> using namespace std; int ans = 0; int fa[50010*3]; void init(int n){ for(int i = 1; i <= n; i++)fa[i]=i; } int find(int x){ return x==fa[x]?x:fa[x]=find(fa[x]); } void merge(int x, int y){ x=find(x);y=find(y);if(x!=y)fa[x]=y;} int some(int x, int y){ return find(x)==find(y); } int main(){ int n, m; cin>>n>>m; init(n*3); for(int i = 1; i <= m; i++){ int op, x, y; cin>>op>>x>>y; if(x>n||y>n){ans++;continue;}//2)当前的话中X或Y比N大,就是假话 if(op==2&&x==y){ans++;continue;}//3)当前的话表示X吃X,就是假话 if(op==1){ if(some(x,y+n)||some(y,x+n))ans++;//如果x吃y或者y吃x,就不是同类 else{ merge(x,y);//x和y是同类 merge(x+n,y+n);//能吃x和y的也是同类 merge(x+n*2,y+n*2);//x和y能吃的也是同类 } }else{ if(some(x,y)||some(y,x+n))ans++;//如果x和y是同类或者y吃x 4000 else{ merge(x,y+n);//x和吃y的连起来 merge(x+n,y+n*2);//能吃x的和被y吃的连起来(三种动物之间的关系啊) merge(x+n*2,y);//x能吃的和y连起来 } } } cout<<ans<<"\n"; return 0; }
相关文章推荐
- vijos1531【noi2001】食物链
- NOI2001 食物链(并茶几)
- POJ1182 【NOI2001】 食物链 <种类并查集>
- NOI2001 食物链 并查集
- NOI 2001 食物链 题解
- 【NOI 2001】codevs1074 食物链
- NOI 2001 食物链 解题报告 (并查集)
- vijos1531 食物链
- 【NOI2001】食物链
- 【NOI2001】食物链
- 【NOI2001T1】食物链-并查集
- 【洛谷 2024】[NOI2001]食物链
- NOI 2001 食物链
- NOI 2001 食物链 并查集A的第一题。
- 【NOI2001】洛谷2024 食物链
- Noi2001 食物链
- poj1182 带权并查集 NOI 2001 食物链(eat) P1531
- codevs 1704 [NOI2001] 食物链 并查集
- [noi2001]聪明的打字员 vijos p1673
- 【带权并查集】POJ1182 [NOI2001]食物链