博客
关于我
程序设计基础18 并查集(一)
阅读量:378 次
发布时间:2019-03-05

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

Mr Wang 想从一群男孩中选出尽可能多的男孩来帮助他的项目。这些男孩之间存在直接或间接的朋友关系。我们的任务是确定最多能留下多少个男孩,使得留下来的每个人都是彼此的朋友或通过共同朋友相连。这个问题可以通过并查集(Union-Find)来高效解决。

思路总结

  • 问题分析:这是一个典型的连通分量问题。每个男孩可以看作图中的一个节点,朋友关系是边。我们需要找到最大的连通分量的大小。

  • 并查集选择:并查集能够高效地管理连通分量,支持快速的合并和查找操作。路径压缩和按秩合并可以提升效率,确保处理大规模数据的性能。

  • 实现步骤

    • 初始化父数组,每个节点最初是自己的父亲。
    • 处理每一对朋友关系,合并他们所在的连通分量。
    • 计算每个节点的根节点,并统计每个根节点的成员数量。
    • 找出最大的成员数量,即为答案。
  • 特殊情况处理:如果没有朋友关系(n=0),最大的连通分量是1个男孩。

  • 代码实现

    #include 
    #include
    using namespace std;
    const int max_n = 10000010;
    int father[max_n] = {0};
    int group_num[max_n] = {0};
    int findFather(int x) {
    int a = x;
    while (x != father[x]) {
    x = father[x];
    }
    while (a != father[a]) {
    int z = a;
    a = father[a];
    father[z] = x;
    }
    return x;
    }
    void Union(int a, int b) {
    int faA = findFather(a);
    int faB = findFather(b);
    if (faA != faB) {
    father[faA] = faB;
    }
    }
    void init() {
    for (int i = 1; i <= max_n; ++i) {
    father[i] = i;
    }
    for (int i = 1; i <= max_n; ++i) {
    group_num[i] = 0;
    }
    }
    int main() {
    int N = 0;
    int x = 0, y = 0;
    while (scanf("%d", &N) != EOF) {
    if (N == 0) {
    printf("1\n");
    continue;
    }
    init();
    int max_id = -1;
    for (int i = 0; i < N; ++i) {
    scanf("%d %d", &x, &y);
    if (x > max_id) {
    max_id = x;
    }
    if (y > max_id) {
    max_id = y;
    }
    Union(x, y);
    }
    for (int i = 1; i <= max_id; ++i) {
    int root = findFather(i);
    group_num[root]++;
    }
    int max_group = 0;
    for (int i = 1; i <= max_id; ++i) {
    if (group_num[i] > max_group) {
    max_group = group_num[i];
    }
    }
    printf("%d\n", max_group);
    }
    return 0;
    }

    代码解释

  • 数据结构初始化father数组记录每个节点的父亲,group_num数组记录每个根节点的成员数量。

  • 查找函数findFather:使用路径压缩优化查找,确保快速找到根节点,并压缩路径减少后续查找的时间。

  • 合并函数Union:按秩合并确保树的平衡,减少合并操作的时间复杂度。

  • 初始化函数init:初始化父数组和成员数量数组,确保每个节点最初都是自己的根节点,成员数量为0。

  • 主函数main:处理输入,逐个处理朋友关系并合并,最后计算并输出最大的连通分量大小。

  • 这个方案能够高效处理大规模数据,确保在合理的时间内完成任务。

    转载地址:http://uolwz.baihongyu.com/

    你可能感兴趣的文章
    nvm安装以后,node -v npm 等命令提示不是内部或外部命令 node多版本控制管理 node多版本随意切换
    查看>>
    ny540 奇怪的排序 简单题
    查看>>
    NYOJ 1066 CO-PRIME(数论)
    查看>>
    nyoj------203三国志
    查看>>
    nyoj58 最少步数
    查看>>
    OAuth2 + Gateway统一认证一步步实现(公司项目能直接使用),密码模式&授权码模式
    查看>>
    OAuth2 Provider 项目常见问题解决方案
    查看>>
    Vue.js 学习总结(14)—— Vue3 为什么推荐使用 ref 而不是 reactive
    查看>>
    oauth2-shiro 添加 redis 实现版本
    查看>>
    OAuth2.0_JWT令牌-生成令牌和校验令牌_Spring Security OAuth2.0认证授权---springcloud工作笔记148
    查看>>
    OAuth2.0_JWT令牌介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记147
    查看>>
    OAuth2.0_介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记137
    查看>>
    OAuth2.0_完善环境配置_把资源微服务客户端信息_授权码存入到数据库_Spring Security OAuth2.0认证授权---springcloud工作笔记149
    查看>>
    OAuth2.0_授权服务配置_Spring Security OAuth2.0认证授权---springcloud工作笔记140
    查看>>
    OAuth2.0_授权服务配置_令牌服务和令牌端点配置_Spring Security OAuth2.0认证授权---springcloud工作笔记143
    查看>>
    OAuth2.0_授权服务配置_客户端详情配置_Spring Security OAuth2.0认证授权---springcloud工作笔记142
    查看>>
    OAuth2.0_授权服务配置_密码模式及其他模式_Spring Security OAuth2.0认证授权---springcloud工作笔记145
    查看>>
    OAuth2.0_授权服务配置_授权码模式_Spring Security OAuth2.0认证授权---springcloud工作笔记144
    查看>>
    OAuth2.0_授权服务配置_资源服务测试_Spring Security OAuth2.0认证授权---springcloud工作笔记146
    查看>>
    OAuth2.0_环境介绍_授权服务和资源服务_Spring Security OAuth2.0认证授权---springcloud工作笔记138
    查看>>