• 侦查帮派问题


    一 问题描述

    警察局决定从两个帮派青龙帮和白蛇帮开始治理混乱,首先需要确定犯罪分子属于哪个团伙。比如,有两名罪犯,他们是否属于同一帮派?警察必须根据不完整的信息做出判断。假设有 N 个罪犯,编号为 1 到 N,其中至少一人属于青龙帮,至少一人属于白蛇帮,请依次给出 M 个消息,消息类型有两种:D a b,表示 a 和 b 属于不同的帮派。A a b,表示查询 a 和 b  是否属于同一帮派。

    二 输入和输出

    1 输入

    第 1 行包含单个整数,即测试用例的个数。每个测试用例都以两个整数 N 和 M 开始;接着是 M 行,每行都包含如上所述的一个信息。

    2 输出

    对每个查询操作,都根据之前获得的信息进行判断,答案可能是 In the same gangs、In the different gangs 和 Not sure yet,分别表示在同一帮派中、在不同帮派中和还不确定。

    三 输入和输出样例

    1 输入样例

    1

    5 5

    A 1 2

    D 1 2

    A 1 2

    D 2 4

    A 1 4

    2 输出样例

    Not sure yet.

    In different gangs.

    In the same gang.

    四 分析

    可以用一个集合表示一个帮派,根据集合号判定是否属于同一帮派。在并查集的基本操作中,Union(x、y) 表示将 x 和 y 合并为同一集合。与并查集的集合合并不同,本问题需要将两者划分为不同的集合。

    1 划分为不同集合的方法

    可以给每个节点 x 都复制一个影子 x+n,将 x、y 划分到不同的集合,只需将 x 和 y 的影子(y+n)合并到一个集合,并将 x 的影子(x+n)和 y 合并为同一集合,执行 Union(x,y+n)、Union(x+n,y),表示将 x 和 y 划分到不同的集合。

    2 判定是否属于同一集合

    因为将 x 和 y 划分到不同集合,与彼此的影子进行了合并,即 x 和 y 的影子(y+n)集合号相同或者 x 的影子(x+n)和 y 集合号相等时,说明 x、y 属于不同的集合;而 x 和 y 集合号相等或者 x 的影子和 y 的影子集合号相等时,说明 x、y 属于同一集合;对于其他情况,不确定是否属于同一集合。

    3 合并优化

    若将高树合并到矮树之下,则合并后的树高增1;若将矮树合并到高树之下,则合并的树高不变。树高越大,查找祖宗时经过的节点越多,效率越低。因此采用启发式合并,将矮树合并到高树之下,若树的高度一样,则合并后树根的高度增1.

    五 算法设计

    1 初始化

    将 n 扩大为 2n 个节点,初始化每个节点的集合号都为其自身高度,高度为0。

    2 划分为不同的集合。

    执行 Union(x,y+n)、Union(x+n,y)、表示 x、y 属于不同的集合。

    3 判定是否属于同一集合

    若 Find(y+n)==Find(x)||Find(x+n)==Find(y),则属于不同的集合;若(Find(x)==Find(y)||Find(x+n)==Find(y+n)),则属于同一集合;否则不确定是否属于同一集合。

    六 图解

    1 初始化

    根据样例,一共有 5 个节点,将其扩大为 10 个节点。初始化每个节点的集合号为自身,高度 h 为 0。

    2 A 1 2

    查询 1 和 2 是否属于同一帮派。Find(1)=1,Find(6)=6,Find(2)=2,Find(7)=7,前两个判定条件都不满足,不确定 1 和 2 是否属于同一帮派。

    3 D 1 2

    将 1 和 2 划分到不同的集合。将 1 和 2+5 合并,将 1+5 和 2 合并。

    4 A 1 2

    查询 1 和 2 是否属于同一帮派。因为 (Find(2+5)==Find(1)|| Find(1+5)==Find(2)),所以 1 和 2 不属于不一帮派。

    5 D 2 4

    将 2 和 4 划分到不同的集合。和一将 2 和 4+5 进行合并,将 2+5 和 4 合并。将高度小的树合并到高度大的树下面,因此将 9 合并 到 2 下面,将 4 合并到 7 下面。

    6 A 1 4

    表示查询 1 和 4 是否属于同一帮派。因为 Find(1)==Find(4)|| Find(1+5)==Find(4+5),因此 1 和 4 属于同一帮派。

    七 代码

    1. package com.platform.modules.alg.alglib.poj1703;
    2. public class Poj1703 {
    3. public String output = "";
    4. private final int MAXN = 200010; // 因为有影子数据量*2,不然会越界!!run time error!!!
    5. private int n;
    6. private int m;
    7. private int fa[] = new int[MAXN];
    8. private int h[] = new int[MAXN]; // h 用来区分树的高度,但其不存储树的具体高度
    9. void Init() {
    10. for (int i = 1; i <= 2 * n; i++) {
    11. fa[i] = i;
    12. h[i] = 0;
    13. }
    14. }
    15. int Find(int x) {
    16. if (x != fa[x])
    17. fa[x] = Find(fa[x]);
    18. return fa[x];
    19. }
    20. void Union(int x, int y) {
    21. int a = Find(x);
    22. int b = Find(y);
    23. if (a == b) return;
    24. if (h[a] > h[b]) //启发式合并,把矮树合并到高树之下
    25. fa[b] = a;
    26. else {
    27. fa[a] = b;
    28. if (h[a] == h[b])//若树的高度一样,合并后树根的树高+1
    29. h[b]++;
    30. }
    31. }
    32. public String cal(String input) {
    33. String[] line = input.split("\n");
    34. String[] words = line[0].split(" ");
    35. n = Integer.parseInt(words[0]);
    36. m = Integer.parseInt(words[1]);
    37. Init();
    38. for (int i = 0; i < m; i++) {
    39. String[] word = line[1 + i].split(" ");
    40. char ch[] = new char[2];
    41. ch[0] = word[0].charAt(0);
    42. int x = Integer.parseInt(word[1]);
    43. int y = Integer.parseInt(word[2]);
    44. if (ch[0] == 'D') {
    45. Union(x, y + n);
    46. Union(x + n, y);
    47. } else {
    48. if (Find(y + n) == Find(x) || Find(x + n) == Find(y))
    49. output += "In different gangs.\n";
    50. else if (Find(x) == Find(y) || Find(x + n) == Find(y + n))
    51. output += "In the same gang.\n";
    52. else
    53. output += "Not sure yet.\n";
    54. }
    55. }
    56. return output;
    57. }
    58. }

    八 测试

  • 相关阅读:
    算法-双指针、BFS与图论-1238. 日志统计
    压力串级控制装置用于气动马达的高精度调节
    为虚拟化环境带来更强I/O性能!SR-IOV技术简介
    主成分分析
    学习Vue3 第一章
    ES-分词器
    一文教你如何通过 Stream API 批量 Mock 数据
    使用 Learner Lab - 学生
    【Java 基础篇】Java类型通配符:解密泛型的神秘面纱
    C#编程学习
  • 原文地址:https://blog.csdn.net/chengqiuming/article/details/126555119