並查集算法詳解

一、基本概念

並查集是一種處理不相交集合的算法,用於解決連接問題。它維護一個森林,每棵樹表示一個集合,樹的根節點表示該集合的代表元,即集合的標識符。並查集可以快速地處理兩個元素是否在同一集合中,以及合併兩個集合的操作。

二、基本操作

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/zh-hk/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

發表回復

登錄後才能評論