Swift Data Structure And Algorithm/Graph Algorithm
ํญ๋ฐ๋ฌผ ์ค์น
youngjaeLee1026
2022. 4. 18. 17:20
1. ๋ฌธ์
2. ์ ์ถ๋ ฅ
3. ์ ์ถ๋ ฅ ์์
4. ๋ฌธ์ ์ค๊ณ
- SCC ๋ฌธ์ ๋ฅผ ์์ฉํ ๋ฌธ์ ๋ก, ์ฝ์ฌ๋ผ์ฃผ ์๊ณ ๋ฆฌ์ฆ์์ ์ญ๋ฐฉํฅ ๊ทธ๋ํ์ ๋ํด์ DFS๋ฅผ ํ๋ฒ ๋ ์ ์ฉํ๋ ๊ฒ๊ณผ ๋ค๋ฅด๊ฒ ์๊ฐํด์ผ ํจ
- ๊ฒฐ๋ก ์ ์ผ๋ก, SCC์ธ ๊ทธ๋ํ๋ค์ ์ด๋ ํ ์ ์ ์ ํฐ๋จ๋ ค๋ ๋ค ํฐ์ง๊ธฐ ๋๋ฌธ์ 1๊ฐ์ ์ ์ ์ผ๋ก ๋ด๋ ๋ฌด๋ฐฉํจ
- ๋ฐ๋ผ์ SCC์ธ ๊ทธ๋ํ๋ค์ 1๊ฐ์ ์ ์ ์ผ๋ก ๋ณด๊ณ , ๋๋จธ์ง์ ๋ํด ๊ฐ์ฅ ํจ์จ์ ์ด๊ฒ ํญ๋ฐ๋ฌผ์ ์ค์นํด์ผ ํ๋๋ฐ, ์์ธํ ์ดํด๋ณด๋ฉด
- ๋์๊ฒ ๋ค์ด์ค๋ ๊ฐ์ ์ด ์๋ ์ ์ ์ ๋ํด ํฐ๋จ๋ฆฌ๊ฒ ๋๋ฉด ๊ฐ์ฅ ์ต์ํ์ ๋ค์ด๋๋ง์ดํธ๋ฅผ ์ฌ์ฉํ์ฌ ํญ๋ฐ๋ฌผ์ ์ค์นํ ์ ์์
- ์ด๋ฅผ ์ฝ์ฌ๋ผ์ฃผ ์๊ณ ๋ฆฌ์ฆ์ ์์ฉํ์ฌ ๋น ์ ธ๋์ค๋ ์์๋ฅผ ๊ธฐ๋กํ๊ณ , ์ฌ๊ทํจ์(DFS)์ ํน์ฑ์ ๊ฐ์ฅ ๋์ค์ ๋น ์ ธ๋์จ ์ ์ ์ด ๋์๊ฒ ๋ค์ด์ค๋ ๊ฐ์ ์ด ์๋ ๊ฐ์ ์ด๋ฏ๋ก, ์ด๋ฒ์๋ ์ญ๋ฐฉํฅ์ด ์๋ ์๋ ์ ๋ฐฉํฅ ๊ทธ๋ํ์ ๋ํด ๊ฐ์ฅ ๋์ค์ ๋น ์ ธ๋์จ ์ ์ ๋ถํฐ DFS๋ฅผ ํ๋ฒ ๋ ์ ์ฉํจ์ผ๋ก์จ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์
- ๋ฐ๋ผ์ O(V + E)์ ์๊ฐ๋ณต์ก๋๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์
5. ์ ์ฒด ์ฝ๋
//MARK: - ํญ๋ฐ๋ฌผ ์ค์น
//MARK: - Framework
import Foundation
//MARK: - Type
struct Graph {
//MARK: - Property
var edges: [Int]
//MARK: - Init
init() {
self.edges = []
}
}
//MARK: - Variable
var graph: [Graph] = []
var visited: [Bool] = []
var orders: [Int] = []
var orderCount: Int = 0
//MARK: - Function
func getOrderDFS(_ x: Int) -> Void {
visited[x] = true
for i in 0..<graph[x].edges.count {
let y: Int = graph[x].edges[i]
if !visited[y] {
getOrderDFS(y)
}
}
orders.append(x)
}
func graphDFS(_ x: Int) -> Void {
visited[x] = true
for i in 0..<graph[x].edges.count {
let y: Int = graph[x].edges[i]
if !visited[y] {
graphDFS(y)
}
}
}
func solution() -> Void {
//MARK: - Input
guard let input: [String] = readLine()?.components(separatedBy: " ") else { return }
let N: Int = input.map { Int($0) }[0] ?? 0
let M: Int = input.map { Int($0) }[1] ?? 0
var dynamiteCount: Int = 0
graph = Array(repeating: Graph(), count: N + 10)
visited = Array(repeating: false, count: N + 10)
for _ in 0..<M {
guard let inputData: [String] = readLine()?.components(separatedBy: " ") else { return }
let a: Int = inputData.map { Int($0) }[0] ?? 0
let b: Int = inputData.map { Int($0) }[1] ?? 0
graph[a].edges.append(b)
}
//MARK: - Process
for i in stride(from: 1, through: N, by: 1) {
if !visited[i] {
getOrderDFS(i)
}
}
visited = Array(repeating: false, count: N + 10)
for i in stride(from: orders.count - 1, through: 0, by: -1) {
if !visited[orders[i]] {
graphDFS(orders[i])
dynamiteCount += 1
}
}
//MARK: - Output
print(dynamiteCount)
}
solution()
์ ์ฒด์ฝ๋๋ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค.