323. 無向圖中連通分量的數目


題目:

鏈接:https://leetcode-cn.com/problems/number-of-connected-components-in-an-undirected-graph/

給定編號從 0 到 n-1 的 n 個節點和一個無向邊列表(每條邊都是一對節點),請編寫一個函數來計算無向圖中連通分量的數目。

示例 1:

輸入: n = 5 和 edges = [[0, 1], [1, 2], [3, 4]]

0 3
| |
1 --- 2 4

輸出: 2
示例 2:

輸入: n = 5 和 edges = [[0, 1], [1, 2], [2, 3], [3, 4]]

0 4
| |
1 --- 2 --- 3

輸出:  1
注意:
你可以假設在 edges 中不會出現重復的邊。而且由於所以的邊都是無向邊,[0, 1] 與 [1, 0]  相同,所以它們不會同時在 edges 中出現。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/number-of-connected-components-in-an-undirected-graph
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。

 

解答:

DFS:維持一個未遍歷過的節點,每次取一個為遍歷過的節點,然后從它開始dfs,遍歷所有可達的節點,也就是找到了一個連通分量。

class Solution {
public:
    int countComponents(int n, vector<vector<int>>& edges) {
        if(n<=0){
            return 0;
        }
        unordered_map<int,unordered_set<int> > edge_map;
        for(auto& edge:edges){
            edge_map[edge[0]].insert(edge[1]);
            edge_map[edge[1]].insert(edge[0]);
        }
        unordered_set<int> unvisited;
        for(int i=0;i<n;++i){unvisited.insert(i);}
        int res=0;
        while(unvisited.size()>0){
            // for(int x:unvisited){
            //     cout<<x<<" ";
            // }cout<<endl;
            auto cur=unvisited.begin();
            dfs(*cur,unvisited,edge_map);
            ++res;
        }
        return res;
    }

    void dfs(int cur,unordered_set<int>& unvisited,unordered_map<int,unordered_set<int> >& edge_map){
        unvisited.erase(cur);
        for(const int& neighbour:edge_map[cur]){
            if(unvisited.count(neighbour)){
                dfs(neighbour,unvisited,edge_map);
            }
        }
    }
};

 

 

 

並差集:(開始沒想到,確實是個好方法)

class Solution {
public:
    vector<int> father;
    int Father(int i){
        if(father[i]!=i){
            return father[i]=Father(father[i]);
        }
        return i;
    }
    void merge(int x,int y){
        int px=Father(x),py=Father(y);
        father[px]=py;
    }
    int countComponents(int n, vector<vector<int>>& edges) {
        father.resize(n);
        for(int i=0;i<n;++i){
            father[i]=i;
        }
        for(auto& edge:edges){
            merge(edge[0],edge[1]);
        }
        unordered_set<int> tmp;
        for(int i=0;i<n;++i){
            if(tmp.count(Father(i))==0){//注意這里要調用Father(i)函數,因為可能i的父親還沒有更新為最靠上的祖先。
                tmp.insert(father[i]);//這里可以直接取father[i]的值,因為上面已經驗證過了,當前father[i]的值一定是最靠上的祖先。
            }
        }
        return tmp.size();
    }   
};

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM