1. 程式人生 > 其它 >LeetCode刷題(每日一題) --1319. 連通網路的操作次數(並查集)

LeetCode刷題(每日一題) --1319. 連通網路的操作次數(並查集)

技術標籤:演算法leetcode演算法網路

題目

用乙太網線纜將 n 臺計算機連線成一個網路,計算機的編號從 0 到 n-1。線纜用 connections 表示,其中 connections[i] = [a, b] 連線了計算機 a 和 b。

網路中的任何一臺計算機都可以通過網路直接或者間接訪問同一個網路中其他任意一臺計算機。

給你這個計算機網路的初始佈線 connections,你可以拔開任意兩臺直連計算機之間的線纜,並用它連線一對未直連的計算機。請你計算並返回使所有計算機都連通所需的最少操作次數。如果不可能,則返回 -1 。

示例 1:

在這裡插入圖片描述

輸入:n = 4, connections = [[0,1],[0,2],[1,2]] 輸出:1 解釋:拔下計算機 1 和 2

之間的線纜,並將它插到計算機 1 和 3 上。

示例 2:

在這裡插入圖片描述

輸入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2],[1,3]] 輸出:2

示例 3:

輸入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2]] 輸出:-1 解釋:線纜數量不足。

示例 4:

輸入:n = 5, connections = [[0,1],[0,2],[3,4],[2,3]] 輸出:0

提示:

1 <= n <= 10^5
1 <= connections.length <= min(n*(n-1)/2, 10^5)

connections[i].length == 2
0 <= connections[i][0], connections[i][1] < n
connections[i][0] != connections[i][1]
沒有重複的連線。
兩臺計算機不會通過多條線纜連線。

解答

關於連通網路的,毫無疑問,可以使用並查集。這樣的話,我們只要在初始化的時候,給並查集的類定義一個count,表示當前的連通量。以及一個多餘的次數rest,即預設一開始有(n)個網路線纜,每次在呼叫Union函式的時候,如果不用進行合併操作,則rest加1,代表著可以剩餘一個線纜。而按照題目,最後還必須將每個單獨的連通量進行合併,則count個連通量需要count-1個線纜。因此,最後結果只要返回以上即可。

程式碼

class UF
{
private:
    vector<int> uf;
    vector<int> rank;
    int count;
    int rest;
public:
    UF(int n):uf(vector<int>(n)),rank(vector<int>(n)),count(n),rest(0)
    {
        for(int i=0;i<n;++i)
            uf[i]=i;
    }
    int Find(int index)
    {
        return uf[index]==index?uf[index]:uf[index]=Find(uf[index]);
    }
    void Union(int index1,int index2)
    {
        int find1 = Find(index1);
        int find2 = Find(index2);
        if(find1!=find2)
        {
            if(find2<find1)
                swap(find1,find2);
            uf[find1]=find2;
            if(rank[find1]==rank[find2]) rank[find2]+=1;
            --count;
        }
        else    ++rest;
    }
    int getCount()
    {
        return count;
    }
    int getRest()
    {
        return rest;
    }
};

class Solution {
public:
    int makeConnected(int n, vector<vector<int>>& connections) {
        UF uf(n);
        for(auto connection:connections)
        {
            uf.Union(connection[0], connection[1]);
        }
        if(uf.getRest()<uf.getCount()-1) return -1;
        return uf.getCount()-1;
    }
};