POJ 1182 食物链
2014-08-27 13:32
204 查看
这是一道很有质量的并查集,做完这题我对并查集又有更深一步的理解了
题意:有编号1到N的A、B、C三类动物,满足A吃B,B吃C,C吃A
然后有K句话说
1 X Y:表示X和Y是同类
2 X Y:表示X吃Y
如果:X或者Y大于N,则是谎话。如果X吃X也是谎话。如果X和Y的关系能确定,并且和这句话给的X、Y的关系矛盾,那么也是谎话
否则这句话便是真话
我觉得这篇解题报告写得很好,里面的思路已经说得很详细了:
http://blog.csdn.net/ditian1027/article/details/20804911
X和Y无非就三种关系,每种关系用一个数表示,这并不稀奇。可厉害的是,在递推关系的时候居然能用统一的表达式表达出来,这就神了!Orz
说说我犯过的两点错误:
压缩路径的同时更新relation数组,开始我写的是
问题在于,回溯的时候parent[a]已经被更新,也就不能用来计算了。所以用一个临时变量temp来暂存a之前的父节点
在合并X、Y的时候,要先找到X和Y所在树的树根px和py然后对两个树根进行合并,否则如果对x、y合并,会出现x和y的树根不等的情况。而且,根据x、y的关系以及和他们父节点的关系来推他们父节点的关系,这个表达式也真是不好想,真乃神人也!
代码君
题意:有编号1到N的A、B、C三类动物,满足A吃B,B吃C,C吃A
然后有K句话说
1 X Y:表示X和Y是同类
2 X Y:表示X吃Y
如果:X或者Y大于N,则是谎话。如果X吃X也是谎话。如果X和Y的关系能确定,并且和这句话给的X、Y的关系矛盾,那么也是谎话
否则这句话便是真话
我觉得这篇解题报告写得很好,里面的思路已经说得很详细了:
http://blog.csdn.net/ditian1027/article/details/20804911
X和Y无非就三种关系,每种关系用一个数表示,这并不稀奇。可厉害的是,在递推关系的时候居然能用统一的表达式表达出来,这就神了!Orz
说说我犯过的两点错误:
压缩路径的同时更新relation数组,开始我写的是
parent[a] = GetParent(parent[a]); relation[a] = (relation[a] + relation[parent[a]]) % 3;
问题在于,回溯的时候parent[a]已经被更新,也就不能用来计算了。所以用一个临时变量temp来暂存a之前的父节点
在合并X、Y的时候,要先找到X和Y所在树的树根px和py然后对两个树根进行合并,否则如果对x、y合并,会出现x和y的树根不等的情况。而且,根据x、y的关系以及和他们父节点的关系来推他们父节点的关系,这个表达式也真是不好想,真乃神人也!
//#define LOCAL #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 50000 + 10; int parent[maxn], relation[maxn]; int GetParent(int a) { if(parent[a] == a) return a; int temp = parent[a]; parent[a] = GetParent(parent[a]); relation[a] = (relation[a] + relation[temp]) % 3; return parent[a]; } int main(void) { #ifdef LOCAL freopen("1182in.txt", "r", stdin); #endif int n, k, r, x, y, cnt = 0; scanf("%d%d", &n, &k); memset(relation, 0, sizeof(relation)); for(int i = 1; i <= n; ++i) parent[i] = i; while(k--) { scanf("%d%d%d", &r, &x, &y); if(x > n || y > n || (x==y && r==2)) { ++cnt; continue; } GetParent(x); GetParent(y); if(parent[x] == parent[y]) { if( (r==1 && relation[x]!=relation[y] ) ||(r==2 && (relation[x]+1)%3 != relation[y]) ) ++cnt; } else { int px = GetParent(x); int py = GetParent(y); parent[py] = px; relation[py] = ((relation[x]-relation[y] + 3) + (r - 1)) % 3; } } printf("%d\n", cnt); return 0; }
代码君
相关文章推荐
- poj——1182食物链(并查集 每种动物扮演三种角色)
- poj 1182 (食物链)
- POJ 1182 :食物链(并查集)
- POJ 1182 食物链 带权并查集
- POJ 1182 食物链
- poj1182 食物链 (种类并查集)
- POJ 1182 - 食物链
- POJ 1182-食物链
- poj 1182 食物链
- POJ 1182(食物链)
- POJ 1182 食物链 带权并查集
- 【并查集】poj 1182 食物链
- POJ 1182 食物链,并查集的拓展
- POJ 1182 食物链
- POJ1182 食物链(并查集)
- POJ 1182 食物链
- 并查集:POJ 1182 食物链 复习
- POJ 1182 食物链(分组解法)——及相同解法一道例题
- poj 1182 食物链
- POJ 1182 食物链(种类并查集 + 偏移量)