zoukankan      html  css  js  c++  java
  • [LintCode] Connected Component in Undirected Graph

    Find the number connected component in the undirected graph. Each node in the graph contains a label and a list of its neighbors. (a connected component (or just component) of an undirected graph is a subgraph in which any two vertices are connected to each other by paths, and which is connected to no additional vertices in the supergraph.)

    Each connected component should sort by label.

     
    Example

    Given graph:

    A------B  C
          |  | 
          |  |
          |  |
          |  |
          D   E
    

    Return {A,B,D}, {C,E}. Since there are two connected component which is {A,B,D}, {C,E}

    Solution 1. BFS

    Algorithm.

    Iterate all nodes in the input graph and do the following.

    1. For each unvisited graph node s, do a bfs starting from it and add all nodes that can be reached from s to a list as one connected component. Add each visited nodes to a global set that tracks which nodes have been visited.

    2. Sort each connected component.

     1 /**
     2  * Definition for Undirected graph.
     3  * class UndirectedGraphNode {
     4  *     int label;
     5  *     ArrayList<UndirectedGraphNode> neighbors;
     6  *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
     7  * };
     8  */
     9 
    10 //Algorithm 1. bfs 
    11 public class Solution {
    12     public List<List<Integer>> connectedSet(ArrayList<UndirectedGraphNode> nodes) {
    13         List<List<Integer>> results = new ArrayList<List<Integer>>();
    14         if(nodes == null || nodes.size() == 0)
    15         {
    16             return results;
    17         }
    18         Set<UndirectedGraphNode> visited = new HashSet<UndirectedGraphNode>();
    19         //bfs on each node to get all the connected components
    20         for(UndirectedGraphNode node : nodes)   
    21         {
    22             if(!visited.contains(node))
    23             {
    24                 bfs(node, visited, results);
    25             }
    26         }
    27         return results;
    28     }
    29     private void bfs(UndirectedGraphNode node, 
    30                     Set<UndirectedGraphNode> visited,
    31                     List<List<Integer>> results)
    32     {
    33         ArrayList<Integer> comp = new ArrayList<Integer>();
    34         Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
    35         queue.offer(node);
    36         visited.add(node);
    37         comp.add(node.label);
    38         
    39         while(!queue.isEmpty())
    40         {
    41             UndirectedGraphNode curr = queue.poll();
    42             for(UndirectedGraphNode neighbor : curr.neighbors)
    43             {
    44                 if(!visited.contains(neighbor))
    45                 {
    46                     queue.offer(neighbor);
    47                     visited.add(neighbor);
    48                     comp.add(neighbor.label);
    49                 }
    50             }
    51         }
    52         Collections.sort(comp);
    53         results.add(comp);
    54     }
    55 }

    Solution 2. Union Find

    Algorithm.

    1. Add each node to a union find data structure and connect these nodes based on the graph edges. A hash map is better suited for the union find since the input graph nodes' labels do not necessarily starts from 0 and are not guranteed to be consecutive. 

    2. Iterate through the uf and create a mapping bewteen a root label and its represented node labels. Sort each map value and add it to the final result.

     1 //Algorithm 2. Union Find
     2 public class Solution {
     3     class UnionFind {
     4         private HashMap<Integer, Integer> father = null;
     5         public UnionFind(HashSet<Integer> labels){
     6             father = new HashMap<Integer, Integer>();
     7             for(Integer i : labels){
     8                 father.put(i, i);
     9             }
    10         }
    11         public int find(int x){
    12             int parent = father.get(x);
    13             while(parent != father.get(parent)){
    14                 parent = father.get(parent);
    15             }
    16             
    17             //compress path
    18             int next;
    19             while(x != father.get(x)){
    20                 next = father.get(x);
    21                 father.put(x, parent);
    22                 x = next;
    23             }
    24             return parent;
    25         }
    26         public void connect(int x, int y){
    27             int root_x = find(x);
    28             int root_y = find(y);
    29             if(root_x != root_y){
    30                 father.put(root_x, root_y);
    31             }
    32         }
    33         
    34     }
    35     public List<List<Integer>> connectedSet(ArrayList<UndirectedGraphNode> nodes) {
    36         List<List<Integer>> results = new ArrayList<List<Integer>>();
    37         if(nodes == null || nodes.size() == 0){
    38             return results;
    39         }
    40         //store all nodes' labels in a hash set
    41         HashSet<Integer> nodeLabels = new HashSet<Integer>();
    42         for(UndirectedGraphNode node : nodes){
    43             nodeLabels.add(node.label);
    44             for(UndirectedGraphNode neighbor : node.neighbors){
    45                 nodeLabels.add(neighbor.label);
    46             }
    47         }
    48         //connect all nodes based on the edges
    49         UnionFind uf = new UnionFind(nodeLabels);
    50         for(UndirectedGraphNode node : nodes){
    51             for(UndirectedGraphNode neighbor : node.neighbors){
    52                 uf.connect(node.label, neighbor.label);
    53             }
    54         }
    55         getAllCC(nodeLabels, uf, results);
    56         return results;
    57     }
    58     private void getAllCC(HashSet<Integer> nodeLabels, UnionFind uf, List<List<Integer>> results){
    59         //key: root representative of each connected component
    60         //value: connected component
    61         HashMap<Integer, List<Integer>> cc = new HashMap<Integer, List<Integer>>();
    62         for(int i : nodeLabels){
    63             int root = uf.find(i);
    64             if(!cc.containsKey(root)){
    65                 cc.put(root, new ArrayList<Integer>());
    66             }
    67             cc.get(root).add(i);
    68         }
    69         //sort answers
    70         for(List<Integer> comp : cc.values()){
    71             Collections.sort(comp);
    72             results.add(comp);
    73         }
    74     }
    75 }

    Related Problems

    Graph Valid Tree

    Find the Weak Connected Component in the Directed Graph

  • 相关阅读:
    【闲聊PHP】编程界的萝莉小美女--PHP
    【福利资料】程序员各种优秀资料、神器及框架
    【夯实shell基础】shell基础面面观
    【Java学习系列】第4课--Java Web相关
    【夯实PHP基础】微信小程序开发 2017.02.06
    【文学文娱】2017.01.17 周二--《谈谈日本妹子(多图预警)》
    【日常开发】使用多种工具实现 sql查询没有结果的name
    【夯实Mysql基础】MySQL在Linux系统下配置文件及日志详解
    【读书笔记】2017.01.06 星期五 《大型网站架构技术》
    【文学文娱】2016.12.23 周五--《我眼中的过年》
  • 原文地址:https://www.cnblogs.com/lz87/p/7496951.html
Copyright © 2011-2022 走看看