食物链------种类并查集
2017-08-16 16:35
204 查看
原题传送门 :http://poj.org/problem?id=1182
推荐blog传送门,超级详细:http://blog.csdn.net/c0de4fun/article/details/7318642/这种题,渣渣我是刚不了的……,百度了一堆帖子,说实话谈到关键代码的真的不是很多,也确实有好的帖子,让我收获了不少。
做题思路:
种类并查集,首先利用一个数组a来确定并查集关系,同时在建立一个数组b来表示某点与他们的boss点(根点)的关系。
现规定:
0: 某点与他的根点为同类
1: 某点与他的根点的关系为, 根点种类的动物的可以吃掉该点种类的动物
2: 某点与他的根点的关系为, 该点种类的动物的可以吃掉根点种类的动物
至于 那两个重要公式(代码已标注),如果自己不想推就去看推荐的那个blog,很详细。
几
4000
点注意:
1.如果两点没有并查集关系,首先给他们确定并查集关系
2. 如果两点有了并查集关系,检验他们所陈述的与根点的关系是否相同
3. 注意 输入的数据大于n的时候 不要让他们进入mergy函数
代码如下
#include <iostream> #include<cstdio> #include<cstring> #include <algorithm> using namespace std; int ans; int a[50100]; int b[50100]; void Init ()//初始化两个数组 { for(int i=1; i<=50100; i++) { a[i]=i; b[i]=0; } } int get_boss(int x) { if(a[x]==x) return x; else { int t=a[x]; a[x]=get_boss(a[x]); b[x]=(b[x]+b[t])%3;//带权并查集式,重要公式1 return a[x]; } } void mergy(int z,int x, int y) { int t1=get_boss(x); int t2=get_boss(y); if(z==1) { if(t1==t2) { if(b[x] != b[y])//false ans++; } else { a[t2]=t1; b[t2] = (b[x]-b[y]+3+(z-1))%3;//重要公式2, 另外+3的原因式剪发可能出现负数,因为模3,,3无所谓 } } else { if(t1==t2) { if( (b[x]+1) %3 !=b[y] ) // false // 下述推导 //(b[x]==0 && b[y]==1) || (b[x]==1 && b[y]==2) || (b[x]==2 && b[y]==0),除了这三种都是错的语句 ans++; } else { a[t2]=t1; b[t2] = (b[x]-b[y]+3+(z-1))%3; } } } int main () { int n,m,x,y,z; scanf("%d %d",&n,&m); Init(); ans=0; while(m--) { scanf("%d %d %d",&z,&x,&y); if(x>n|| y>n) ans++; //false else if(x==y && z==2) ans++; // false else mergy(z,x,y);// n<x, n<y 千万不要让他们进来,错了N遍 } printf("%d\n",ans); return 0; }
相关文章推荐
- POJ 1182 食物链 种类并查集
- POJ 1182 食物链(种类并查集)
- 食物链(种类并查集)
- poj 食物链(种类并查集)(思路)
- POJ1182 食物链---(经典种类并查集)
- POJ 1182 食物链(种类并查集 + 偏移量)
- POJ 1182 食物链(种类并查集)
- poj1182 食物链 (种类并查集)
- poj 食物链(种类并查集)(思路)
- poj 食物链 种类并查集
- poj1182~食物链~种类并查集
- POJ1182:食物链(种类并查集)
- POJ1182 食物链 种类并查集(经典)
- poj1182 食物链(种类并查集)详解
- poj 食物链(种类并查集)(思路)
- POJ 1182 食物链 (三态种类并查集)
- poj 食物链(种类并查集)(思路)
- POJ 1182 食物链 (三态种类并查集)
- POJ 1182 食物链(种类并查集)
- 【POJ 1182】 食物链 【种类并查集】