题目:找出有向图中的弱联通分量

来源:互联网 发布:centos jdk rpm 编辑:程序博客网 时间:2024/04/28 14:26
请找出有向图中弱联通分量的数目。图中的每个节点包含其邻居的 1 个标签和1 个列表。 (一个有向图中的相连节点指的是一个包含 2 个通过直接边沿路径相连的顶点的子图。)

您在真实的面试中是否遇到过这个题?

Yes





样例

给定图:
A----->B  C
\     |  |
  \    |  |
   \   |  |
    \  v  v
     ->D  E <- F


返回 {A,B,D}, {C,E,F}. 图中有 2 个相连要素,即{A,B,D} 和 {C,E,F} 。

挑战

将原素升序排列。
标签 Expand   



相关题目 Expand 

解题思路:
非常典型的并查集算法。
将有关联的元素重新组合在一个集合中。
并查集主要分3步:
1.初始化集合
2.查找集合    这里有多种方式优化,一般推荐压缩路径
3.合并集合
以下资料很详细的解释了并查集算法。
http://baike.baidu.com/link?url=686sDo92aljz0C0M-Sq4xyLewz2auwuPOrYkPwkA5uPjwWdNzWYH619ATjL4NWpGWwVEQJL0P3qEmzob9F4QWq
http://www.cnblogs.com/pangxiaodong/archive/2011/05/27/2059547.html
http://www.cnblogs.com/vongang/archive/2011/07/31/2122763.html

WA代码,没有考虑元素中值为负数情况,直接使用数组作为father集合。

/*** Definition for Directed graph.* class DirectedGraphNode {*     int label;*     ArrayList<DirectedGraphNode> neighbors;*     DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }* };*/public class Solution {    /**     * @param nodes a array of Directed graph node     * @return a connected set of a directed graph     */     int father[] = new int[10000];     public List<List<Integer>> connectedSet2(ArrayList<DirectedGraphNode> nodes) {        // Write your code here         List<List<Integer>>  res = new ArrayList<>();         if(nodes==null||0==nodes.size()) return res;         ArrayList<Integer> visited = new ArrayList<>();         for(DirectedGraphNode node:nodes)         father[node.label] = node.label;         for(DirectedGraphNode node:nodes){              for(DirectedGraphNode neigbor:node.neighbors){                   merge(node.label,neigbor.label);              }         }         for(DirectedGraphNode node:nodes){              int  sfather = find(node.label);              if(visited.contains(sfather)){                   continue;              }                          List<Integer> sameFather = new ArrayList<>();             for(int i=0;i<nodes.size();i++){                  if(sfather==find(nodes.get(i).label)){                       sameFather.add(nodes.get(i).label);                  }             }             if(sameFather.size()!=0&&null!=sameFather)             {     res.add(sameFather);                   visited.add(sfather);             }         }        return res;    }    public int find(int x){         if(x!=father[x]){              father[x] = find(father[x]);         }         return father[x];    }    public void merge(int x,int y){         int xfather = find(x);         int yfather = find(y);         if(xfather!=yfather){              father[yfather] = xfather;         }    }}

AC代码:用MAP来作为集合

/*** Definition for Directed graph.* class DirectedGraphNode {*     int label;*     ArrayList<DirectedGraphNode> neighbors;*     DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }* };*/public class Solution {    /**     * @param nodes a array of Directed graph node     * @return a connected set of a directed graph     */     HashMap<Integer, Integer> father = new HashMap<>();     public List<List<Integer>> connectedSet2(ArrayList<DirectedGraphNode> nodes) {        // Write your code here         List<List<Integer>>  res = new ArrayList<>();         if(nodes==null||0==nodes.size()) return res;         ArrayList<Integer> visited = new ArrayList<>();         for(DirectedGraphNode node:nodes)              father.put(node.label, node.label);              for(DirectedGraphNode node:nodes){              for(DirectedGraphNode neigbor:node.neighbors){                   merge(node.label,neigbor.label);              }         }         for(DirectedGraphNode node:nodes){              int  sfather = find(node.label);              if(visited.contains(sfather)){                   continue;              }                          List<Integer> sameFather = new ArrayList<>();             for(int i=0;i<nodes.size();i++){                  if(sfather==find(nodes.get(i).label)){                       sameFather.add(nodes.get(i).label);                  }             }             if(sameFather.size()!=0&&null!=sameFather)             {     res.add(sameFather);                   visited.add(sfather);             }         }        return res;    }    public int find(int x){         if(x!=father.get(x)){              father.put(x, find(father.get(x)));         }         return father.get(x);    }    public void merge(int x,int y){         int xfather = find(x);         int yfather = find(y);         if(xfather!=yfather){              father.put(yfather, xfather);         }    }}


0 0