博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1182 食物链
阅读量:5172 次
发布时间:2019-06-13

本文共 1521 字,大约阅读时间需要 5 分钟。

  食物链是一道经典的并查集题,这道题难在怎么确定两个动物之间的关系。

看了罗德安大神的分析,有种豁然开朗的感觉。

问题分析:

    我们把已经确立了关系的动物分到一个群落里,对于每一个提到的两个数字编号, 看它们是

否属于同一个群落,如果是的那么根据它们已有的关系,我们作出相应的判断 即可;若它们属于

不同的群落,那么根据互相的关系将两个群落合并;若恰有一个没有 加入到任意一个群落之中,

那么将这一个并入另一个的群中即可;若两个都未加入任意 群中,那么我们新建一个群即可。

基本思路:

这一题的难点在于记录动物之间的关系,即ABC三种动物是循环被吃的,我们用 0,1,2表示,记录

在rank[i]中,如果i吃j,则让rank[i]=(rank[j]+1)%3.为了便于处理, rank[i]表示第i个动物相对

于其父节点动物的差值,而不直接表示他本身的类别。这样 我们可以通过并查集自身的性质巧妙的

维护rank[]的值,所有根结点的rank[]值为0.

/*Accepted    512K    329MS    C++    1029B    2012-08-08 15:23:35*/#include
#include
#include
const int MAXN = 50050;int p[MAXN], rank[MAXN];int n, k, op, ans;int find_set(int x){ int t = p[x]; if(p[x] != x) p[x] = find_set(p[x]); rank[x] = (rank[x] + rank[t]) % 3; return p[x];}void union_set(int x, int y, int op){ int nx = find_set(x); int ny = find_set(y); p[nx] = ny; rank[nx] = (rank[y] - rank[x] + 3 + op - 1) % 3;}int judge(int x, int y, int op){ if(find_set(x) == find_set(y)) { if(rank[x] != (rank[y] + op - 1) % 3 ) return 1; } return 0;}int main(){ int i, x, y; scanf("%d%d", &n, &k); ans = 0; for(i = 1; i <= n; i ++) { p[i] = i; rank[i] = 0; } while(k --) { scanf("%d%d%d", &op, &x, &y); if(x > n || y > n || judge(x, y, op)) ++ ans; else union_set(x, y, op); } printf("%d\n", ans); return 0;}

 

 

 

转载于:https://www.cnblogs.com/Yu2012/archive/2012/08/08/2628354.html

你可能感兴趣的文章
set&map
查看>>
集合类总结
查看>>
4.AE中的缩放,书签
查看>>
1.开发准备
查看>>
centos su命令
查看>>
CLR:基元类型、引用类型和值类型
查看>>
dubbo序列化hibernate.LazyInitializationException could not initialize proxy - no Session懒加载异常的解决...
查看>>
jQuery中的事件绑定的几种方式
查看>>
泥塑课
查看>>
setImageBitmap和setImageResource
查看>>
springMVC4 注解配置实例
查看>>
单片机编程
查看>>
Filter in Servlet
查看>>
Linux--SquashFS
查看>>
Application Pool Identities
查看>>
2017-3-24 开通博客园
查看>>
【MySQL性能优化】MySQL常见SQL错误用法
查看>>
Vue2全家桶之一:vue-cli(vue脚手架)超详细教程
查看>>
Struts 2 常用技术
查看>>
树形DP
查看>>