POJ-1182-食物链 解题报告
来源:互联网 发布:ubuntu mount ntfs 编辑:程序博客网 时间:2024/06/08 20:14
这是一道关系型并查集的题目,题目意思就不赘述了,毕竟是中文描述。
接下来讲我的解题思路,开一个存储父节点的数组和一个存储与父节点关系的数组(我们姑且称之为这个节点的关系数),然后用数字0代表同类,1代表吃,2代表被吃的关系。用并查集将两个不知道关系的节点相连,并根据输入情况是吃与被吃来为子节点的与父节点的关系赋值。
查找一个节点的祖先节点(也就是根节点)时我们要进行路径压缩把这个节点的父节点修改为根节点,然而这个节点与父亲节点的关系(也就是这个节点的关系数)应该怎么修改呢?其实不难通过验证发现,将这个节点到根节点之间的所有节点的关系数(不包括根节点,但包括初始节点)相加求的和再对3取余就是这个节点与根节点的关系。
合并是当两个节点x,y不属于同一个集合时进行的,也就是说它们的根节点fx,fy不相同,这个时候根据输入的数据我们可以知道x与y的关系,查找x和y的根节点可以让我们知道x与fx,y与fy的关系,那么我们就可以根据这些关系推导得出fx与fy的关系,事实上,这一对关系的关系数是有公式可循的(在代码中会有),现在就可以合并fx与fy了。
另外,题目要求输出假话的总数,在种类为2,3的假话我们很容易就可以判断的了,而种类为1的假话如何判断呢?首先输入的节点x和y必须是拥有共同的根节点我们才可以判断输入的话是否是假话,否则必然是真话。其次因为我们知道x和y分别与他们共同的根节点的关系,所以我们可以推导出x与y的关系,然后我们判断这个关系与输入的关系是否一样就可以了。
注意:如果写成多组测试就会WA,坑啊!
接下来是我的解题代码
#include <stdio.h>#define N 50001int bleg[N]; /*存储父节点*/int rela[N]; /*存储与父节点的关系,0代表同类,1代表吃,2代表被吃*/int fake = 0; /*假话的数量*/int n, k;void Init(); /*初始化*/int Find(int x); /*查找根节点*/void Union(int x, int y, int que); /*合并操作*/int main(){ int x, y; int que; /*输入的关系*/ scanf("%d %d", &n, &k); Init(); while (k--) { scanf("%d %d %d", &que, &x, &y); if ((que == 2 && x == y) || x > n || y > n) /*满足2或3类别的假话*/ { fake++; continue; } if (Find(x) != Find(y)) /*当且仅当两个节点的根节点不相同时才合并*/ { Union(x, y, que); } else { rela[x] %= 3; rela[y] %= 3; if (que == 1 && rela[x] != rela[y]) /*表示x与y的实际关系与que为1表示的关系冲突*/ { fake++; } else if (que == 2 && !(rela[x] == rela[y] + 1 || (rela[y] == 2 && rela[x] == 0))) { fake++; } } } printf("%d\n", fake); return 0;}void Init() /*初始化*/{ int i; for (i=1; i<=n; i++) { bleg[i] = i; rela[i] = 0; } return;}int Find(int x) /*用于查找根节点*/{ int y = bleg[x]; while (y != bleg[y]) /*当你的父节点不是根节点,开始修改你与父节点的关系*/ { rela[x] += rela[y]; y = bleg[y]; } bleg[x] = y; /*把父节点修改为根节点*/ return y;}void Union(int x, int y, int que) /*合并操作*/{ int fx = Find(x); int fy = Find(y); bleg[fx] = fy; /*先将根节点合并*/ rela[x] %= 3; rela[y] %= 3; /*接下来是分别判断x和y与其根节点的关系*/ if (rela[x] == rela[y]) /*表示x和y分别与其根节点的关系是一样的*/ { rela[fx] = que - 1; /*对应的公式*/ } else if (rela[x] == rela[y] - 1 || (rela[x] == 2 && rela[y] == 0)) /*另外一组关系*/ { rela[fx] = que; /*又是对应的公式*/ } else { rela[fx] = (que + 1) % 3; } return;}
- POJ-1182-食物链 解题报告
- POJ 1182 食物链 -- 解题报告
- poj 1182 食物链 解题报告
- POJ1182 食物链 解题报告
- 【解题报告】 POJ 1182 食物链 并查集的经典应用+相对位置
- poj 1182 食物链(并查集)解题报告(转)
- Poj 食物链 解题报告 (种类并查集)
- POJ 1182 解题报告
- 食物链 并查集 解题报告
- 艰难的食物链的解题报告
- 【NOI2000/codevs1074/tyvj1438】食物链 解题报告
- 【解题报告】食物链[codevs 1074][rqnoj 455]
- poj解题报告——1182
- POJ 1182 并查集 解题报告
- poj数百篇解题报告
- poj 1141解题报告
- poj 1001解题报告
- poj 1011 解题报告
- Cocos2dx 小技巧(十三)聊聊坐标系
- SharedPreferences
- 终于赶在软件测试部前头解决Access数据库压缩的问题
- leetcode第一刷_Distinct Subsequences
- 5月7号-坚持
- POJ-1182-食物链 解题报告
- 本地new int[]的处理
- 【Android】自定义控件——仿天猫Indicator
- sqli-labs从零开始学习日记 开心的第一步
- 克33+9爆利拉德阿德32分 马刺24分大胜开拓者
- 关于Date Time Picter的初始化和保存
- coco2dx 3.0 在安卓上按返回键没有作用
- 黑马程序员——java基础之环境变量设置
- 游标的简单例子