如何检查二分图中存在的简单路径

时间:2013-05-27 12:02:20

标签: algorithm graph

我有一个有向图的外向结构:

a{f}=[d e];
a{d}=[c];
a{e}=[c h];
a{h}=[b];
a{c}=[a b];

其中a{f}=[d e]表示节点de是节点f的外向邻域。

现在,我的目标是确定是否存在两条路径,一条是从fa,另一条是从fb,其节点是不允许彼此相交?

对于这个例子,答案是肯定的,因为我们可以找到两条路径:

p1: f->d->c->a
p2: f->e->h->b

但是当我们删除图表中的边h->b时,答案是否定的,因为即使有两条路径:

p1: f->d->c->a
p3: f->e->c->b

但是,路径p3的节点c与路径p1相交。

  f
 / \
d   e
 \ / \
  c   h
 / \ /
a   b

我的问题是:是否有任何算法来检查两条路径的存在?

2 个答案:

答案 0 :(得分:1)

您正在寻找的是AB支配者,其中起始点为F的流程图。如果从VA的每条路径都经过F,则A会占据V。因此,对于您的特定问题,您可以:

  • 计算并浏览A的所有支配者,标记除F
  • 之外的那些顶点
  • 计算并浏览B的所有支配者,如果标记了任何顶点:

    - > AB至少有一个共同支配者D,因此没有两个顶点不相交(除了包含F)路径F->A和{{1可以存在,因为每个路径F->B和每个路径F->A都会通过F->B

请参阅http://en.wikipedia.org/wiki/Dominator_(graph_theory)#Algorithms

答案 1 :(得分:1)

您可以通过以下方法使用max-flow算法解决此问题:

  1. 通过将每个顶点拆分为入口顶点并退出顶点
  2. 来构造有向图
  3. 从条目(i)到退出(i)添加边缘,每个容量为1,基于顶点i
  4. 从出口(i)到条目(j)添加边缘,对于原始图表中的每个边缘i-> j,容量为1
  5. 添加额外的终端顶点e
  6. 为每个目的地(在您的情况下退出(a)和退出(b))的出口顶点添加一条边到容量为1的顶点e
  7. 从退出(f)到e
  8. 计算maximum flow

    当且仅当最大流量为2时,则有两条从f到a / b的顶点不相交路径。

    Python代码示例

    import networkx as nx
    G=nx.DiGraph()
    a={'f':'de','d':'c','e':'ch','h':'b','c':'ab','a':'','b':''}
    for v in a:
        i='entry_'+v
        j='exit_'+v
        G.add_edge(i,j,capacity=1)
        for dest in a[v]:
            G.add_edge(j,'entry_'+dest,capacity=1)
    for dest in 'ab':
        G.add_edge('exit_'+dest,'e',capacity=1)
    print nx.max_flow(G,'exit_f','e')
    
    G.remove_edge('exit_h','entry_b')
    print nx.max_flow(G,'exit_f','e')
    

    打印

    2 (meaning that in the original graph there are 2 vertex disjoint paths)
    1 (meaning that once we remove h->b, there is only 1 vertex disjoint path)