題目:
鏈接: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(); } };