๐ง Biconnected Components
๊ทธ๋ํ $G$ ๊ฐ biconnected ํ๋ค๋ ๊ฒ์ ๋ค์์ ์๋ฏธํฉ๋๋ค.
$G$ ๋ connected graph ์ด๋ฉฐ, articulation point๋ฅผ ๊ฐ์ง๊ณ ์์ง ์๋ค.
biconnected๋ฅผ ํตํ biconnected component์ ์ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Biconnected component $G’$ of $G$ : $G$ ์ maximal biconnected subgraph
์ฆ $G$ ์ biconnected component๋ก $G$ ์ ๊ฐ์ ๋ค์ partitioning ํ ์ ์์ผ๋ฉฐ,
์๋ก ๋ค๋ฅธ biconnected component๋ ์ต๋ ํ๊ฐ์ ์ ์ (articulation vertex)๋ฅผ ๊ณต์ ํฉ๋๋ค.
๋ฐ๋ผ์ ์์ ๊ทธ๋ฆผ์ฒ๋ผ Articulation Point๋ฅผ ํตํด ๊ทธ๋ํ ๋ด์ ์กด์ฌํ๋ Biconnected Components๋ฅผ ์ฐพ์๋ผ ์ ์์ต๋๋ค.
โญ๏ธ Key Property
๊ฐ์ BCC์ ์ํด์๋ edge $e$ ์ $e'$ ์ด ์์ ๋,
$e = e'$ ์ด๊ฑฐ๋ $e$ ์ $e'$ ์ ๋ชจ๋ ํฌํจํ๋ cycle์ด ๊ฐ์ component ์์ ์ํด์์ต๋๋ค.
์ฆ๋ช ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๊ฐ์ BCC ์์ ์กด์ฌํ๋ edge $e$ ์ $e'$ ์ด ์์ ๋,
$e \neq e'$ ์ด๋ฉฐ $e$ ์ $e'$ ์ ๋ชจ๋ ํฌํจํ๋ cycle์ด ๊ฐ์ bcc ์์ ์๋ค๊ณ ๊ฐ์ ํ๊ฒ ์ต๋๋ค.
$e$ ์ $e'$ ๋ฅผ ๋ชจ๋ ํฌํํ๋ cycle์ ์ํ๋ฉด์ ์ด๋ค๊ณผ ๊ฐ์ bcc์ ์ํ์ง ์๋ ์ ์ ์ $u$ ๋ผ๊ณ ํ๋ฉด,
$e$ ์ $e' $์ด ์ํ BCC์ ์์์ ํ ์ ์ ์ผ๋ก๋ถํฐ $u$ ๊น์ง์ path ๊ฐ ๋ฌด์กฐ๊ฑด ์กด์ฌํฉ๋๋ค.
(์กด์ฌํ์ง ์์ผ๋ฉด cycle์ด ์ฑ๋ฆฝํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.)
๋ํ $u$ ๋ $e$, $e'$ ๊ณผ ๊ฐ์ cycle์ ์ํ๊ธฐ ๋๋ฌธ์ $e$, $e'$ ๊ฐ ์ํ BCC์ ์์์ ํ ์ ์ ์ ์ ๊ฑฐํ๋๋ผ๋ ์ฌ์ ํ $u$๋ก์ path๊ฐ ์กด์ฌํฉ๋๋ค.
๋ํ ๊ฐ์ ์ ์ํ์ฌ ๊ธฐ์กด $e$ ์ $e' $ ๋ฅผ ํฌํจํ๋ BCC๋ $u$ ๋ฅผ ํฌํจํ์ง ์์ ์ํ๋ก BCC ์๊ธฐ ๋๋ฌธ์ $u$ ๋ Articulation Point๊ฐ ์๋๋๋ค.
๋ฐ๋ผ์ ๊ธฐ์กด BCC์ $u$ ๋ฅผ ์ถ๊ฐํ๋๋ผ๋ ์ฌ์ ํ BCC์ด๋ฏ๋ก, maximal ์กฐ๊ฑด์ ์๋ฐฐ๋ฉ๋๋ค.
๋ฐ๋ผ์ ๊ฐ์ ์ ๋ชจ์์ด ์กด์ฌํ๋ฏ๋ก, ์ฆ๋ช ์ด ์๋ฃ๋ฉ๋๋ค.
๐ง Biconnected Conponent ์ฐพ์๋ด๋ ์๊ณ ๋ฆฌ์ฆ
์ฐ์ ํด๋น ์๊ณ ๋ฆฌ์ฆ์ ๋์์ด ๋๋ ๊ทธ๋ํ $G$ ๋ Connencted graph์ ๋๋ค.
Biconnected Component๋ Articulation Point๋ฅผ ํตํด ์ฐพ์๋ผ ์ ์์ต๋๋ค.
Biconnected Component๋ฅผ ๊ตฌํ๊ธฐ ์ํด ๋ค์ ๋๊ฐ์ง์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํฉ๋๋ค.
์ฒซ๋ฒ์งธ ๋ฌธ์ : ๊ทธ๋ํ $G$ ์ ๋ชจ๋ Articulation point ์ฐพ๊ธฐ
๋๋ฒ์งธ ๋ฌธ์ : ์ฒซ๋ฒ์งธ ๋ฌธ์ ๋ฅผ ์ด์ฉํด์ $G$ ์ Biconnected Component ์ฐพ๊ธฐ
์ด์ ์ด ๋ ๊ณผ์ ์ ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
โ๏ธ ์ฒซ๋ฒ์งธ ๋ฌธ์ : ๊ทธ๋ํ $G$ ์ ๋ชจ๋ Articulation Point ์ฐพ๊ธฐ
์ด์ ๊ธ์์ ์ดํด๋ณด์์ต๋๋ค.
โ๏ธ ๋๋ฒ์งธ ๋ฌธ์ : Articulation Point ๋ฅผ ์ด์ฉํ์ฌ Biconnected Component ์ฐพ๊ธฐ
์ด๊ณณ์์๋ Graph๋ Undirected Connected Graph๋ผ ๊ฐ์ ํฉ๋๋ค.
Biconnected Component๋ edge๋ฅผ Partitioning ํฉ๋๋ค.
๋ฐ๋ผ์ Biconnected Component๋ฅผ ํ๋ return ํ ๋๋ง๋ค, ํด๋น Component์ ์ํด์๋ edge๋ค์ returnํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํ ์ ์์ต๋๋ค.
ํด๋น ์๊ณ ๋ฆฌ์ฆ์ Stack์ ์ด์ฉํ์ฌ ๊ตฌํํ๋ฉด ๊ฐํธํฉ๋๋ค.
๋ฐ๋ผ์ Stack์ ์ฌ์ฉํ๋ค๋ ์กฐ๊ฑด ํ์ ํด๋น ์๊ณ ๋ฆฌ์ฆ์ ๊ณผ์ ์ ์ค๋ช ํ๋๋ก ํ๊ฒ ์ต๋๋ค.
์ ์ $v$ ๋ฅผ explore ํ๋ฉด์ ๊ฐ์ $($ $v$, $u$ $)$ ๋ฅผ ํ์ธํ ๋๋ง๋ค ํด๋น ๊ฐ์ ์ Stack์ push ํฉ๋๋ค.
๋ง์ฝ $v$ ๋ฅผ explore ํ๋ฉด์, $v$ ์ ์์ ๋ ธ๋ $u$ ์ ์ํ์ฌ,
$v$ ๊ฐ articulation point์์ด ๋ฐํ์ง๊ฑฐ๋( = $low(u)$ $\geq$ $pre(v)$ ),
root node $v$ ์ ํ child ๋ํ explore ๊ฐ ์ข ๋ฃ๋๋ค๋ฉด
๊ฐ์ $($ $u$ , $v$ $)$ ๊ฐ ๋์ฌ ๋๊น์ง, stack ์์ ๋ชจ๋ ๊ฐ์ ๋ค์ pop ํ๋ฉฐ,
์ด๊ฒ๋ค์ด ํ๋์ Biconnected Component๊ฐ ๋ฉ๋๋ค.
Articulation Point๋ฅผ ์ฐพ์ ๋์๋ ๋ฌ๋ฆฌ root node์ธ ๊ฒฝ์ฐ๋ฅผ ๋ฐ๋ก ์ฒ๋ฆฌํ ํ์๊ฐ ์์ต๋๋ค.
์๋ ์ฝ๋
๊ตฌํ
๋ง์ฐฌ๊ฐ์ง๋ก ๋ค์ ๊ทธ๋ํ์ ๋ํ ๊ตฌํ์ ๋๋ค.
/**
* Created by ShinD on 2022/09/22.
*/
fun main() {
val graph = GraphMaker().make()
val biConnectedComponents = mutableListOf<List<Edge>>()
GraphExplorer().findBiConnectedComponent(
graph = graph,
current = GraphMaker.b,
stack = ArrayDeque(),
biConnectedComponents = biConnectedComponents,
)
GraphMaker.vertexSet().forEach {
println("END [${it.value}], [ ${it.preOrder}, ${it.postOrder} ], LOW = [${it.low}], IS_CUT_POINT = [${it.isCutPoint}]")
}
println()
biConnectedComponents.forEach { biConnectedComponent ->
println("BiConnected Component")
biConnectedComponent.forEach {
println("${it.startVertex.value}, ${it.endVertex.value}")
}
println()
println()
}
}
class Graph(
val vertexSet: Set<Vertex>,
val graph: List<List<Vertex>>,
)
class GraphMaker {
companion object {
val a = Vertex('1')
val b = Vertex('2')
val c = Vertex('3')
val d = Vertex('4')
val e = Vertex('5')
val f = Vertex('6')
val g = Vertex('7')
val h = Vertex('8')
fun vertexSet(): Set<Vertex> {
return setOf(
a, b, c, d, e, f, g, h,// i, j, k, l
)
}
}
fun make(): Graph {
return Graph(
vertexSet = vertexSet(),
graph = listOf(
listOf(b, c), // 1
listOf(a, c, d, e), // 2
listOf(a, b), // 3
listOf(b, e, f), // 4
listOf(b, d, f), // 5
listOf(d, e, g, h), // 6
listOf(f, h), // 7
listOf(f, g), // 8
)
)
}
}
class Vertex(
val value: Char,
var preOrder: Int = 0,
var postOrder: Int = 0,
var low: Int = 0,
var isVisited: Boolean = false,
var isCutPoint: Boolean = false,
)
class Edge(
val startVertex: Vertex,
val endVertex: Vertex,
){
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Edge) return false
if (startVertex != other.startVertex) return false
if (endVertex != other.endVertex) return false
return true
}
override fun hashCode(): Int {
var result = startVertex.hashCode()
result = 31 * result + endVertex.hashCode()
return result
}
}
class GraphExplorer {
// ์์ ์ 1๋ก ์ด๊ธฐํ
private var counter = 1
private fun visited(vertex: Vertex) {
vertex.isVisited = true
println("VISIT [${vertex.value}]")
}
private fun preVisit(vertex: Vertex) {
vertex.preOrder = counter
counter++
}
private fun postVisit(vertex: Vertex) {
vertex.postOrder = counter
counter++
}
fun findBiConnectedComponent(
graph: Graph, // Connected Graph
current: Vertex, // DFS ์งํํ Vertex
parent: Vertex? = null,
stack: ArrayDeque<Edge>,
biConnectedComponents: MutableList<List<Edge>>
) {
val idx = current.value - '1'
// ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ
visited(current)
// preVisit
preVisit(current)
// PreOrder ๊ฐ์ผ๋ก low ์ค์
current.low = current.preOrder
// ๋ฃจํธ vertex์ adjacent ํ ๋ชจ๋ vertex ํ์
graph.graph[idx].forEach { vertex ->
// Back Edge์ธ ๊ฒฝ์ฐ
if (vertex.isVisited && vertex != parent ) {
current.low = Math.min(current.low, vertex.preOrder)
stack.add(Edge(current, vertex))
}
// ์์ง ๋ฐฉ๋ฌธํ์ง ์์๋ค๋ฉด explore
if (!vertex.isVisited) {
stack.add(Edge(current, vertex))
findBiConnectedComponent(graph, vertex, current, stack, biConnectedComponents)
current.low = Math.min(current.low, vertex.low)
if (vertex.low >= current.preOrder) { // ์์ ๋
ธ๋(vertex) ์์ ํ์ฌ ๋
ธ๋(current)์ proper ancestor๋ก ํฅํ๋ Back Edge๊ฐ ์๋ ๊ฒฝ์ฐ
current.isCutPoint = true; // current๋ Articulation Point(Cut Point)
val biConnectedComponent = mutableListOf<Edge>()
while (!stack.isEmpty()) {
if (stack.last() == Edge(current, vertex)) { // ๊ฐ์ Edge๊ฐ ๋์ค๋ฉด ์ข
๋ฃ
biConnectedComponent.add(stack.removeLast())
break
}
biConnectedComponent.add(stack.removeLast())
}
biConnectedComponents.add(biConnectedComponent)
}
}
}
postVisit(current)
}
}
'๐ฅ Computer Science > ์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๊ณ ๋ฆฌ์ฆ] ๊ทธ๋ํ (6) - ์์ ์ ๋ ฌ(Topological Sort) (1) | 2022.09.24 |
---|---|
[์๊ณ ๋ฆฌ์ฆ] ๊ทธ๋ํ (5) - Directed Graph ์์์ DFS (0) | 2022.09.24 |
[์๊ณ ๋ฆฌ์ฆ] ๊ทธ๋ํ (3) - ์ฐ๊ฒฐ ์์(Connected Components)์ ๋จ์ ์ (Articulation Point) (0) | 2022.09.24 |
[์๊ณ ๋ฆฌ์ฆ] ๊ทธ๋ํ (2) - DFS (0) | 2022.09.24 |
[์๊ณ ๋ฆฌ์ฆ] ๊ทธ๋ํ (1) - ๊ทธ๋ํ์ ๊ธฐ๋ณธ ์ฉ์ด (0) | 2022.09.24 |