poj 1182 食物链(经典种类并查集)
来源:互联网 发布:数码大师类似软件 编辑:程序博客网 时间:2024/05/27 10:43
看了大佬的博客,终于对种类并查集有了自己的理解。现写下这篇博客,加深自己对种类并查集的理解~
题目链接:http://poj.org/problem?id=1182
题目大意:都是中文没啥好说的。。。
思路:每个种类就相当于一个集团,给这个集团加个权值代表这个集团。(种类并查集也是加权并查集的一 种)。
主要是group(集团之后都用gp表示)
0 代表这个节点的和父节点的关系是同类
1代表这个节点吃他的父节点吃
2代表这个节点被他的父节点吃,也吃gp为1的节点
然后有了gp食物链就链接成功了。
然后是树的权值的更新
并查集三部:
建树: 每个数的跟节点赋值为本身,gp为0,未被讨论的都属于0,初始化的时候用inline可以加速
find:找到这个数的根节点(递归还是函数都是可以的),在返回前,跟新一下这个节点和父节点的关系
gp[i]=(gp[i]+gp[pa[i]])%3;//这里有个很重要的事情, 就是先压缩再更新这个我会在某个并查集中详细写一下推导!!!
unite:先进行路径压缩,更新权值 ,如果以前确定了关系,那么的话就在食物链内就可以直接验证真假关系,如果不在就并入食物链中
代码:
#include<cstdio>const int max=50000+50; int gp[max],pa[max];inline void init(int n){ for(int i=1;i<=n;i++) pa[i]=i,gp[i]=0;}int find(int x){ if(x==pa[x]) return x; int fa=find(pa[x]); gp[x]=(gp[x]+gp[pa[x]])%3; return pa[x]=fa;}int unite(int d,int x,int y){ int fx=find(x); int fy=find(y); if(fx==fy){ if(d==1&&gp[x]!=gp[y]) return false; if(d==2&&(gp[y]+1)%3!=gp[x]) return false; return true; } gp[fx]=(gp[x]-gp[y]+3+d-1)%3; pa[fx]=fy; return true; }int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { init(n); int d,x,y,sum=0; for(int i=0;i<m;i++){ scanf("%d%d%d",&d,&x,&y); if(x>n||y>n||(d==2&&x==y)) { sum++; continue; } if(find(x)==find(y)){ if(d==2&&(gp[y]+1)%3!=gp[x]) sum++; if(d==1&&gp[y]!=gp[x]) sum++; } else { if(!unite(d,x,y)) sum++; } } printf("%d\n",sum); } return 0; }
阅读全文
0 0
- poj 1182 食物链(经典!种类并查集)
- poj 1182 食物链 (种类并查集经典题)
- POJ - 1182 食物链(种类并查集经典题)
- poj 1182 食物链(经典种类并查集)
- poj 1182 食物链(种类并查集)
- POJ 1182 食物链 种类并查集
- POJ 1182 食物链(种类并查集)
- poj 1182 食物链 (种类并查集)
- POJ 1182 食物链(种类并查集)
- poj 1182 食物链 种类并查集
- poj 1182食物链【种类并查集】
- 食物链 - POJ 1182 种类并查集
- POJ 1182 食物链 (种类并查集)
- POJ 1182 食物链(种类并查集)
- POJ-1182-食物链 [种类并查集]
- POJ 1182 食物链 (种类并查集)
- POJ 1182 食物链 (三态种类并查集)
- POJ-1182 食物链 (种类并查集)
- 高斯日记
- 掌握这些常见的操作git就基本可以平趟了
- Mybatis配置过程——增删改查实例
- 选项卡,数组,年历
- 杭电1108 最小公倍数
- poj 1182 食物链(经典种类并查集)
- windows7旗舰版,vs2015下配置opencv3.3.0
- 自学总结2
- linux 5
- 【Unity】Unity Mac版本破解
- bzoj1206: [HNOI2005]虚拟内存
- CAP理论十二年回顾:"规则"变了
- QT
- java中的BigDecimal和String的相互转换