博客
关于我
C - 食物链 并查集
阅读量:388 次
发布时间:2019-03-05

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

为了解决这个问题,我们需要处理动物王国中三种动物A、B、C的食物链关系,这些关系构成一个环。我们需要根据给定的N个动物和K句话,判断其中有多少句子是假话。

方法思路

我们可以使用并查集(Union-Find)数据结构来高效地处理同类和食物链关系。并查集能够帮助我们快速地合并和查找集合,适合处理大量数据。

具体步骤如下:

  • 初始化并查集:我们需要三个并查集结构来分别处理同类、被吃和吃的关系。
  • 处理每个句子
    • 检查是否有超出范围的情况。
    • 检查是否与已确认的真关系冲突。
    • 如果不是假话,合并相应的关系。
  • 统计假话:每次处理一个句子时,检查是否为假话,并计数。
  • 解决代码

    #include 
    #include
    using namespace std;struct UnionFind { int parent; int rank; UnionFind(int size) : parent(size), rank(0) {} int find(int x) { if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } void union(int x, int y) { x = find(x); y = find(y); if (x == y) return; if (rank[x] < rank[y]) { parent[x] = y; } else { parent[y] = x; if (rank[x] == rank[y]) { rank[x]++; } } }};int main() { int N, K; scanf("%d %d", &N, &K); int size = 3 * N * 2; UnionFind class_parent(size); UnionFind eat_parent(size); UnionFind eatby_parent(size); int ans = 0; for (int i = 0; i < K; i++) { int D, X, Y; scanf("%d %d %d", &D, &X, &Y); // 检查X或Y是否超过N if (X > N || Y > N) { ans++; continue; } // 检查X是否等于Y if (X == Y) { ans++; continue; } bool is_conflict = false; if (D == 1) { // 检查X和Y是否是同类 if (class_parent.find(X) == class_parent.find(Y)) { is_conflict = true; } else { // 检查X是否吃Y int eat_Y = Y + N; if (eat_parent.find(X) == eat_parent.find(eat_Y)) { is_conflict = true; } else { // 检查Y是否吃X int eat_X = X + N; if (eatby_parent.find(Y) == eatby_parent.find(eat_X)) { is_conflict = true; } } } } else if (D == 2) { // 检查X是否吃Y int eat_Y = Y + N; if (eat_parent.find(X) == eat_parent.find(eat_Y)) { is_conflict = true; } else { // 检查Y是否吃X int eat_X = X + N; if (eatby_parent.find(Y) == eatby_parent.find(eat_X)) { is_conflict = true; } } } if (is_conflict) { ans++; continue; } // 处理为真话,更新并查集结构 if (D == 1) { // 合并X和Y的同类 class_parent.union(X, Y); // 合并X+N和Y+N的被吃关系 eatby_parent.union(X + N, Y + N); // 合并X+2N和Y+2N的吃关系 eat_parent.union(X + 2 * N, Y + 2 * N); } else { // 合并Y和X+2N的被吃关系 eatby_parent.union(Y, X + 2 * N); // 合并Y+N和X+N的吃关系 eat_parent.union(Y + N, X + N); // 合并Y+2N和X+2N的吃关系 eat_parent.union(Y + 2 * N, X + 2 * N); } } printf("%d\n", ans); return 0;}

    代码解释

  • 并查集结构:定义了一个UnionFind结构,用于处理并查集操作,包括查找和合并。
  • 读取输入:读取N和K,然后初始化三个并查集结构。
  • 处理每个句子
    • 检查是否超出范围或重复。
    • 检查是否与已确认的真关系冲突。
    • 如果是真话,合并相应的关系。
  • 统计假话数:每次处理一个句子时,检查是否为假话,并计数。
  • 输出结果:最后输出假话的总数。
  • 转载地址:http://tcszz.baihongyu.com/

    你可能感兴趣的文章
    POJ - 1328 Radar Installation 贪心
    查看>>
    CSUOJ Water Drinking
    查看>>
    自定义博客园博客的背景图片
    查看>>
    Spring MVC+javamail实现邮件发送
    查看>>
    Asp.NET Core 限流控制-AspNetCoreRateLimit
    查看>>
    gRPC在 ASP.NET Core 中应用学习(一)
    查看>>
    @SuppressWarnings 用法
    查看>>
    看完你就明白的锁系列之锁的状态
    查看>>
    看完这篇操作系统,和面试官扯皮就没问题了
    查看>>
    我的价值观
    查看>>
    真香!Linux 原来是这么管理内存的
    查看>>
    一文详解 Java 并发模型
    查看>>
    阅站无数!不过我只推荐下面这些
    查看>>
    值类型与引用类型(中)
    查看>>
    MSSQL 2005 数据库变成可疑状态
    查看>>
    QBlog V2.5 源码开放下载(ASP.NET 番外系列之开端)
    查看>>
    秋色园引发CPU百分百命案的事件分析与总结
    查看>>
    安装jdk并配置环境变量
    查看>>
    稀疏数组
    查看>>
    js的严格模式
    查看>>