设为首页 加入收藏

TOP

算法余晖(三)
2018-02-26 08:40:12 】 浏览:1214
Tags:算法 余晖
isc [i] = -1 low [i] = -1 end for u from 1 to the number of vertex in g if disc[i] != -1 TARJAN-STRONGLY-CONNECTED-COMPONENTS-UTIL(u,disc,low,stack,isInStack) end TARJAN-STRONGLY-CONNECTED-COMPONENTS-UTIL(u,disc,low,stack,isInStack) let time be static time = time + 1 disc[u] = low[u] = time stack.push(u) isInStack[u] = true for v equal to every vertex adjacent to u if disc[v] == -1 TARJAN-STRONGLY-CONNECTED-COMPONENTS-UTIL(v,disc,low,stack,isInStack) low[u] = min(low[u],low[v]) else if isInStack[v] == true low[u] = min(low[u],disc[v]) end let w = 0 if low[u] == disc[u] while stack.top() != u w = stack.top() isInStack[w] = false stack.pop() print w end w = stack.top() isInStack[w] = false stack.pop() print w print '\n Found a Strongly Connected Components \n'

时间复杂度:Θ(V+E),V表示顶点的个数,E表示边的个数

图的割点(Articulation Points)、桥(Bridge)、双连通分量(Biconnected Components)

  • 图的割点(Articulation-Points)

图的割点也叫图的关节点,定义为无向图中分割两个连通分量的点,或者说去掉这个点,图中的连通分量数增加了。可以看到如果求出了连通分量,那么不同连通分量中间的顶点就是割点。什么时候某个顶点不是这样的割点?如果这个顶点的子孙顶点有连接这个顶点祖先顶点的边,那么去掉这个顶点,这个顶点的子孙顶点和祖先顶点仍然连通。那么,寻找割点的过程就等价于寻找子孙顶点没有连接祖先顶点的顶点。这个问题的求解过程类似于Tarjan强连通分量的求解过程。

不过,这个问题有个例外就是根顶点,对一般顶点的处理方式处理根顶点行得通吗?根顶点肯定没有子孙顶点指向祖先顶点,但是根顶点可以是割点。所以,根顶点需要特殊处理。根顶点什么时候是割点?当根顶点有多颗子树,且之间无法互相到达的时候。那么,存不存在根顶点有多颗子树,且之间可以互相到达?不存在,如果互相之间可以到达,那在根顶点搜索第一颗子树的时候,就会搜索到可到达的子树,就不会存在多颗子树了。所以,根顶点有多颗子树,那么这多颗子树之间一定无法互相到达。根顶点有多颗子树,且之间无法互相到达的时候就等价于根顶点有多颗子树。所以,只要根顶点有多颗子树,那么根顶点就是割点。

同样地,数组disc表示顶点被访问顺序的编号,数组low表示顶点所在的强连通分量编号。数组parent找出根顶点。

伪代码:
ARTICULATION-POINTS(g)
  let disc be new Array
  let low be new Array
  let result be new Array
  let parent be new Array
  let visited be new Array
  for i from 1 to the number of vertex in g
    result [i] = false
    visited [i] = false
    parent [i] = -1
  end
  for u from 1 to the number of vertex in g 
    if visited[i] == false
      ARTICULATION-POINTS-UTIL(u,disc,low,result,parent,visited)
  end
  for i from 1 to the number if vertex in g
    if result[i] == true
      print '\n Found a Articulation Points i \n'
  end
  
ARTICULATION-POINTS-UTIL(u,disc,low,result,parent,visited)
  let time be static
  time = time + 1
  let children = 0
  disc[u] = low[u] = time
  visited[u] = true
  for v equal to every vertex adjacent to u
    if visited[v] == false
      children = children + 1
      parent[v] = u
      ARTICULATION-POINTS-UTIL(u,disc,low,result,parent,visited)
      low[u] = min(low[u],low[v])
      if parnet[u] == -1 and children > 1
        result[u] = true
      if parent[u] != -1 and low[v] >= disc[u]
        result[u] = true
    else if v != parent[u]
      low[u] = min(low[u],disc[v])
  end

时间复杂度:Θ(V+E),V表示顶点的个数,E表示边的个数

  • 桥(Bridge)

桥定义为一条边,且去掉这个边,图中的连通分量数增加了。类似于寻找割点,寻找桥就是寻找这样一条,一端的顶点的子孙顶点没有连接这个顶点和其祖先顶点的边。求解过程和求割点基本一致。

伪代码:
BRIDGE(g)
  let disc be new Array
  let low be new Array
  let parent be new Array
  let visited be new Array
  for i from 1 to the number of vertex in g
    visited [i] = false
    parent [i] = -1
  end
  for u from 1 to the number of vertex in g 
    if visited[i] == false
      BRIDGE-UTIL(u,disc,low,parent,visited)
  end
  
BRIDGE-UTIL(u,disc,low,parent,visited)
  let time be static
  time = time + 1
  disc[u] = low[u] = time
  for v equal to every vertex adjacent to u
    if visited[v] == false
      parent[v] = u
      BRIDGE-UTIL(u,disc,low,parent,visited)
      low[u] = min(low[u],low[v])
      if low[v] > disc[u]
        print '\n Found a Bridge u->v \n'
    else if v != pa
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 3/9/9
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇通向架构师的道路 ( 第十七天 ) I.. 下一篇精练代码:一次 Java 函数式编程..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目