數據結構 -- 圖中二分圖檢測

二分圖

二分圖又稱作二部圖,是圖論中的一種特殊模型。 設G=(V,E)是一個無向圖,如果頂點V可分割爲兩個互不相交的子集(A,B),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(i in A,j in B),則稱圖G爲一個二分圖。圖A和圖C屬於二分區,圖B不屬於二分圖。
在這裏插入圖片描述


二分圖檢測

染色法

如上圖,對圖中頂點染色,從其中一個頂點開始染爲紅色,相鄰頂點染爲黑色,依次遍歷,將整個圖中頂點染上紅黑顏色。若是出現衝突。視爲二分圖檢測失敗。上圖B就出現衝突,1-3,1-2,2-3邊出現衝突。所以圖B不是二分圖。


scala實現

import util.control.Breaks.{break, _}

class BiPartitionDetection {
  private var G: Graph = _
  private var visited: Array[Boolean] = _
  private var colors: Array[Int] = _
  private var beBiPartite = true

  def this(g: Graph) {
    this()
    G = g
    visited = Array.ofDim[Boolean](g.getV())
    colors = Array.ofDim[Int](g.getV())
    for (i <- 0 until g.getV()) {
      colors(i) = -1
    }
    breakable(
      for (j <- 0 until g.getV()) {
        if (!visited(j)) {
          if (!dfs(j, 0)) {
            beBiPartite = false
            break()
          }
        }
      }
    )
  }

  private def dfs(v: Int, color: Int): Boolean = {
    var result = true
    visited(v) = true
    colors(v) = color
    for (w <- G.getAdjacentSide(v)) {
      if (!visited(w)) {
        if (!dfs(w, 1 - color)) {
          result = false
          result
        }
      } else if (colors(w) == colors(v)) {
        result = false
        result
      }
    }
    result
  }

  def isBiPartite(): Boolean = {
    beBiPartite
  }
}

object BiPartitionDetection {
  def apply(g: Graph): BiPartitionDetection = new BiPartitionDetection(g)

  def main(args: Array[String]): Unit = {
    val g1 = Graph("./data/graph/g.txt")
    val bi1 = BiPartitionDetection(g1)
    println(bi1.isBiPartite())

    val g2 = Graph("./data/graph/g2.txt")
    val bi2 = BiPartitionDetection(g2)
    println(bi2.isBiPartite())

    val g3 = Graph("./data/graph/g3.txt")
    val bi3 = BiPartitionDetection(g3)
    println(bi3.isBiPartite())
  }
}

//true
//false
//true

g.txt

7 6
0 1
0 2
1 3
1 4
2 3
2 6

g2.txt

4 6
0 1
0 2
0 3
1 2
1 3
2 3

g3.txt

4 4
0 1
0 3
1 2
2 3
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章