并查集算法详解

一、基本概念

并查集是一种处理不相交集合的算法,用于解决连接问题。它维护一个森林,每棵树表示一个集合,树的根节点表示该集合的代表元,即集合的标识符。并查集可以快速地处理两个元素是否在同一集合中,以及合并两个集合的操作。

二、基本操作

1. 查找(find)

查找操作是并查集最常用的操作,用于判断两个元素是否在同一集合中,就是判断它们是否有相同的根节点。


// 查找操作
int find(vector& parents, int x) {
    if (parents[x] != x) {
        parents[x] = find(parents, parents[x]);
    }
    return parents[x];
}

在查找操作时,我们使用路径压缩优化,将x到根节点的路径上的所有节点直接与根节点相连,以提高后续查找操作的效率。

2. 合并(union)

合并操作主要用于将两个不相交的集合合并成一个集合,将一棵树的根节点连接到另一棵树的根节点上,此时新的根节点成为新集合的代表元。


// 合并操作
void merge(vector& parents, vector& ranks, int x, int y) {
    int px = find(parents, x), py = find(parents, y);
    if (px != py) {
        if (ranks[px]  ranks[py]) {
            parents[py] = px;
        } else {
            parents[px] = py;
            ranks[py]++;
        }
    }
}

在合并操作时,我们使用了秩(rank)优化,将较小的树连接到较大的树上,以防止树的深度过大产生退化。

3. 初始化(initialize)

在使用并查集前,需要先对每一个元素建立自己的集合,即将每个元素的父节点指向自己。初始化过程可以使用以下代码实现:


// 初始化操作
void init(vector& parents) {
    for (int i = 0; i < parents.size(); i++) {
        parents[i] = i;
    }
}

三、应用场景

1. 判断图中是否存在环

使用并查集可以判断一个无向图中是否存在环。对于每条边(u,v),我们查找u和v所在的集合,若它们在同一集合中,则说明存在环;否则,我们将它们合并为同一集合。


// 判断无向图是否存在环
bool hasCycle(vector<pair>& edges, int n) {
    vector parents(n);
    init(parents);
    for (auto& edge : edges) {
        int px = find(parents, edge.first), py = find(parents, edge.second);
        if (px == py) {
            return true;
        }
        merge(parents, px, py);
    }
    return false;
}

2. 等价关系判断

使用并查集可以快速地判断两个元素是否等价,即它们是否在同一集合中。我们可以维护一个等价类集合,将同一等价类的元素合并到一个集合中,以便于后续处理。


// 判断两个元素是否等价
bool isEquivalent(vector<vector>& eqClasses, int x, int y) {
    for (auto& eqClass : eqClasses) {
        int px = find(eqClass, x), py = find(eqClass, y);
        if (px == py) {
            return true;
        }
    }
    return false;
}

// 将等价类合并
vector<vector> mergeEqClasses(vector<vector>& eqClasses, int x, int y) {
    vector newEqClass;
    for (auto& eqClass : eqClasses) {
        int px = find(eqClass, x), py = find(eqClass, y);
        if (px != py) {
            for (auto& e : eqClass) {
                if (find(eqClass, e) == px || find(eqClass, e) == py) {
                    newEqClass.push_back(e);
                }
            }
        }
    }
    if (newEqClass.empty()) {
        newEqClass.push_back(x);
        newEqClass.push_back(y);
        eqClasses.push_back(newEqClass);
    } else {
        for (auto& eqClass : eqClasses) {
            if (find(eqClass, x) != -1 || find(eqClass, y) != -1) {
                eqClass = newEqClass;
                break;
            }
        }
    }
    return eqClasses;
}

3. 连通性判断

使用并查集可以快速地判断一个图是否是连通的。我们可以使用并查集维护所有的边集合中的点,若最终所有点都在同一集合中,则说明图是连通的。


// 判断图是否连通
bool isConnected(vector<pair>& edges, int n) {
    vector parents(n);
    init(parents);
    for (auto& edge : edges) {
        int px = find(parents, edge.first), py = find(parents, edge.second);
        merge(parents, px, py);
    }
    int root = find(parents, 0);
    for (int i = 1; i < n; i++) {
        if (find(parents, i) != root) {
            return false;
        }
    }
    return true;
}

四、总结

并查集是一种快速处理不相交集合的算法,其核心是查找和合并操作。在实际应用中,我们可以通过并查集判断图中是否存在环,判断元素之间是否存在等价关系,以及判断图是否连通等。不同应用场景下,我们可以灵活地使用并查集的不同操作来解决问题。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/157475.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-11-18 20:00
下一篇 2024-11-18 20:00

相关推荐

  • 蝴蝶优化算法Python版

    蝴蝶优化算法是一种基于仿生学的优化算法,模仿自然界中的蝴蝶进行搜索。它可以应用于多个领域的优化问题,包括数学优化、工程问题、机器学习等。本文将从多个方面对蝴蝶优化算法Python版…

    编程 2025-04-29
  • Python实现爬楼梯算法

    本文介绍使用Python实现爬楼梯算法,该算法用于计算一个人爬n级楼梯有多少种不同的方法。 有一楼梯,小明可以一次走一步、两步或三步。请问小明爬上第 n 级楼梯有多少种不同的爬楼梯…

    编程 2025-04-29
  • AES加密解密算法的C语言实现

    AES(Advanced Encryption Standard)是一种对称加密算法,可用于对数据进行加密和解密。在本篇文章中,我们将介绍C语言中如何实现AES算法,并对实现过程进…

    编程 2025-04-29
  • Harris角点检测算法原理与实现

    本文将从多个方面对Harris角点检测算法进行详细的阐述,包括算法原理、实现步骤、代码实现等。 一、Harris角点检测算法原理 Harris角点检测算法是一种经典的计算机视觉算法…

    编程 2025-04-29
  • 数据结构与算法基础青岛大学PPT解析

    本文将从多个方面对数据结构与算法基础青岛大学PPT进行详细的阐述,包括数据类型、集合类型、排序算法、字符串匹配和动态规划等内容。通过对这些内容的解析,读者可以更好地了解数据结构与算…

    编程 2025-04-29
  • 瘦脸算法 Python 原理与实现

    本文将从多个方面详细阐述瘦脸算法 Python 实现的原理和方法,包括该算法的意义、流程、代码实现、优化等内容。 一、算法意义 随着科技的发展,瘦脸算法已经成为了人们修图中不可缺少…

    编程 2025-04-29
  • 神经网络BP算法原理

    本文将从多个方面对神经网络BP算法原理进行详细阐述,并给出完整的代码示例。 一、BP算法简介 BP算法是一种常用的神经网络训练算法,其全称为反向传播算法。BP算法的基本思想是通过正…

    编程 2025-04-29
  • 粒子群算法Python的介绍和实现

    本文将介绍粒子群算法的原理和Python实现方法,将从以下几个方面进行详细阐述。 一、粒子群算法的原理 粒子群算法(Particle Swarm Optimization, PSO…

    编程 2025-04-29
  • Python回归算法算例

    本文将从以下几个方面对Python回归算法算例进行详细阐述。 一、回归算法简介 回归算法是数据分析中的一种重要方法,主要用于预测未来或进行趋势分析,通过对历史数据的学习和分析,建立…

    编程 2025-04-28
  • 象棋算法思路探析

    本文将从多方面探讨象棋算法,包括搜索算法、启发式算法、博弈树算法、神经网络算法等。 一、搜索算法 搜索算法是一种常见的求解问题的方法。在象棋中,搜索算法可以用来寻找最佳棋步。经典的…

    编程 2025-04-28

发表回复

登录后才能评论