【并查集】数据结构与算法实验题 11.3 培养箱分配问题
2009-08-12 01:08
423 查看
数据结构与算法实验题 11.3 培养箱分配问题 ★ 问题描述 : 生物学家 Finder 最近发现了一种有趣的虫子 BUG , BUG 有两种性别,当 相 同性别 的 BUG 生活在一起时,会发生剧烈的打斗,而当不同性别的 BUG 在一 起时,则 会 相处的非常好。 现在, Finder 找到了很多 BUG 虫,并将它们命名为 1 系列、 2 系列、 3 系 列 …… N 系列,每个系列的 BUG 虫之间是同性别的。 Finder 要将它们分配到培 养箱里培养,每个箱里两只。为了防止同性别之间的打斗,要求每个箱子里的 BUG 虫是不同性 别 的。 ★ 实验任务: 现在 Finder 拟定了一个分配方案,但由于培养箱数量太多, Finder 也不能 确 定这种分配方案是否可行,即同一个培养箱中的 BUG 虫 会 不会打斗。现在, Fi nder 找到你,要你写一个程序验证他的分配方案是否可行。 ★ 数据输入: 由 input.txt 给出输入。第一行有两个数 N , M ,表示 Finder 有 N 个系列的 BUG 虫,编号为 1 到 N , M 表示有 M 个培养箱,接下来 M 行每行两个数 A,B ,表 示 将 A 系列的 BUG 虫和 B 系列的 BUG 虫 放在 一起培养 (1<=A<=N,1<=B<=N) 。 注 意,输入数据有多组,必须处理到文件末尾。 ★ 结果输出 : 输出到 ouput.txt 文件。每个方案输出一行,如果方案可行,输出 YES , 否 则输出 NO 。 ★ 提示 : 多组数据 处理到文件末尾 的伪代码如下: 输入示例 input.txt 3 3 2 1 2 3 3 1 输出示例 output.txt NO
本题可以使用路径压缩来加快速度,但是由于调试原因,所以没有加入。
不过要过ZOJ应该还是要使用路径压缩和 union小树到大树的。
我的思想是
例如这样一组数据
6 8
1 2
3 4
5 6
1 4
3 6
4 5
1 3
1 6
当出现1 2时候
我们把1和2各自归为一个集合,并且这两个集合是相对的。
当3 4时,因为还都是独立的元素,所以再各自归为一个集合,并且这两个集合是相对的。
当5 6时,因为还都是独立的元素,所以再各自归为一个集合,并且这两个集合是相对的。
当出现1 4时 因为 1 和4 都已经是集合的元素了,所以我们把那两个相对的集合合并。
也就是变成了(1 3)-(2 4)
当出现3 6时,因为 3 和6 都已经是集合的元素了,所以我们把那两个相对的集合合并。
也就是变成了(1 3 5 )-(2 4 6)
当出现4 5的时候,因为是出现在相对集合里面,所以不进行操作。
当出现1 3的时候,由于出现在同一个集合里面,所以不符合要求!可以输出no
#include <stdio.h> int Find(int n, bool root[], int Set[]) { int i; i = n; while(1) { if (root[i] == true) return i; i = Set[i]; } } int main() { int m,n; int a,b; int flag; int i; int RootA,RootB; int Set[3000]; bool root[3000]; while (scanf("%d%d", &n, &m)!=EOF) { for(i=0;i<=n;i++) { Set[i] = i; root[i] = true; } flag = 0; for (i=0;i<m;i++) { scanf("%d%d", &a, &b); if (flag) continue; RootA = Find(a ,root, Set); RootB = Find(b,root, Set); if (RootA == RootB) flag = 1; else { if (Set[RootA]==RootA&&Set[RootB]==RootB) { root[RootA] = true; root[RootB] = true; Set[RootA] = RootB; Set[RootB] = RootA; } else if (Set[RootA]==RootA&&Set[RootB]!=RootB) { root[RootA] = false; root[RootB] = true; Set[RootA] = Set[RootB]; } else if (Set[RootB]==RootB&&Set[RootA]!=RootA) { root[RootB] = false; root[RootA] = true; Set[RootB] = Set[RootA]; } else if (Set[RootB]!=RootB&&Set[RootA]!=RootA) { root[RootA] = false; root[Set[RootA]] = false; root[RootB] = true; root[Set[RootB]] = true; //已经在两个相对集合里面了,就不要再改变了 if (Set[RootA] != RootB) { Set[Set[RootA]] = RootB; Set[RootA] = Set[RootB]; } } } } if (flag) printf("NO/n"); else printf("YES/n"); } return 0; }
相关文章推荐
- 数据结构与算法实验题 11.3 最小权语言问题
- 数据结构与算法实验题 11.3 最小权语言问题
- 【并查集】数据结构与算法实验题 11.2 病毒排查问题
- 数据结构与算法实验题 11.1 堆箱子问题
- 数据结构与算法-实验3-自定义栈,并实现走迷宫问题
- 数据结构及算法 - 约瑟夫问题 - javascript
- 【数据结构与算法】topK问题
- 数据结构与算法问题 朋友圈
- 数据结构与算法10:马踏棋盘问题(骑士周游问题)
- [算法]数据结构算法背包问题解法之递归解法,C语言实现
- 数据结构实验:连通分量个数(并查集)
- 数据结构——算法之(040)(最大公约数问题)
- sdutacm-数据结构实验之二叉树七:叶子问题
- 数据结构与算法问题 二叉搜索树
- 数据结构与算法经典问题解析 Java语言描述pdf
- 数据结构与算法实验题 7.1 M 商人的求救
- 一个表空间有多个数据文件,新增数据时的写入顺序和分配算法初探实验(上)
- 一个表空间有多个数据文件,新增数据时的写入顺序和分配算法初探实验(下)_2
- 数据结构实验之二叉树七:叶子问题
- (2013-4-21)数据结构实验三:狐狸逮兔问题(方法二:链式)