检查图表是否为DFS中的二分图

时间:2017-08-06 15:29:51

标签: algorithm graph runtime time-complexity

我想知道我的算法的复杂程度是什么以及为什么用来检查图形(以邻居列表的形式给出)是否是使用DFS的二分图。

该算法的工作原理如下:

  • 我们将使用边缘分类,并寻找后边缘。
  • 如果我们找到一个,则表示图表中有一个圆圈。
  • 我们现在将检查周期是否为奇数周期,使用添加到每个顶点的pi属性,计算参与周期的边数。
  • 如果循环是奇数,则返回false。否则,继续这个过程。

最初我认为复杂性为O(| V | + | E |)为| V |代表图中的顶点数,| E |代表图中边的数量,但恐怕可能需要O(| V | + | E | ^ 2),我想知道哪个选项是正确的和为什么(它可能不是以上任何一个也是)。摊销或预计的运行时间也可能不同,我想知道如何检查它们。

伪代码

DFS(G=(V,E))
// π[u] – Parent of u in the DFS tree 
1 for each vertex u ∈ V {
2 color[u] ← WHITE
3 π[u]← NULL
4 time ← 0}
5 for each vertex u ∈ V {
6 if color[u] = WHITE
7 DFS-VISIT(u)}

和DFS-Visit:

DFS-Visit(u)
// white vertex u has just been discovered
1 color[u] ← GRAY
2 time ← time+1
3 d[u] ← time
4 for each v ∈ Adj[u] { // going over all edges {u, v}
5 if color[v] = WHITE {
6 π[v] ← u
7 DFS-VISIT(v) }
8 else if color[v] = GRAY // there is a cycle in the graph 
9 CheckIfOddCycle (u, v); 
10 color[u] ← BLACK
// change the color of vertex u to black as we finished going over it
11 f[u] ← time ← time+1 

以及决定它是什么类型的循环:

CheckIfOddCycle(u, v)
1 int count  ← 1; 
2 vertex p = u; 
3 while (p! = v) {
4 p ← π[p]  
5 count++ }
6 if count is an odd number {
7 S.O.P (“The graph is not bipartite!”); 
8 stop the search, as the result is now concluded!

谢谢!

1 个答案:

答案 0 :(得分:3)

要确定图形是否为二分图,请执行覆盖整个图形中所有边的DFS或BFS,并且:

  • 当您开始与所有先前顶点断开连接的新顶点时,将其涂成蓝色;
  • 当您发现连接到蓝色顶点的新顶点时,将其涂成红色;
  • 当您发现连接到红色顶点的新顶点时,将其涂成蓝色;
  • 当您找到先前发现的顶点的边缘时,如果它将蓝色连接到蓝色或红色连接到红色,则返回FALSE。
  • 如果您完成整个图表,请返回TRUE。

该算法在BFS或DFS之上只需要很少的工作,因此是O(| V | + | E |)。

此算法本质上也与您问题中的算法相同。当我们发现两侧颜色相同的后缘时,意味着我们刚刚发现的周期是奇数。

但实际上这个算法与周期无关。图形可以比顶点或边缘具有更多的周期,并且DFS或BFS不一定全部找到它们,因此我们正在搜索奇数周期并不准确。

相反,我们只是试图建立一个二分区并返回它是否可能这样做。