youngjaeLee1026
2022. 4. 18. 17:14
1. ๋ฌธ์
2. ์ ์ถ๋ ฅ
3. ์ ์ถ๋ ฅ ์์
4. ๋ฌธ์ ์ค๊ณ
- ๋ฐฉํฅ ๊ทธ๋ํ์์ ๊ฐ์ ๊ทธ๋ฃน์ ์ ์ ์ด๋ผ๋ฉด ์๋ก ์ค๊ณ ๊ฐ์ ์๋ ๊ฒฝ๋ก๊ฐ ์กด์ฌํ๋ ๊ทธ๋ฃน๋ผ๋ฆฌ ๊ทธ๋ํ๋ฅผ ๋๋๋ ๊ฒ์ SCC(Strongly Connected Component)๋ผ๊ณ ํ๋ฉฐ, ์ด๋ฅผ ๊ตฌํ ์ ์๋ ๋ํ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ด ์ฝ์ฌ๋ผ์ฃผ ์๊ณ ๋ฆฌ์ฆ
- ๋ฐ๋ผ์ ์ฃผ์ด์ง ๊ทธ๋ํ๋ฅผ ์ ๋ฐฉํฅ ๊ทธ๋ํ์ ์ญ๋ฐฉํฅ ๊ทธ๋ํ ๋๊ฐ์ง๋ก ๊ตฌ์ฑํ๊ณ , ์ ๋ฐฉํฅ ๊ทธ๋ํ์ ๋ํด DFS๋ฅผ ์ ์ฉํ์ฌ ๋น ์ ธ๋์ค๋ ์์๋๋ก ๊ทธ ์ ์ ์ ๋ฒํธ๋ฅผ ๊ธฐ๋กํ๊ณ , ๊ฐ์ฅ ๋์ค์ ๋น ์ ธ๋์จ ์ ์ ์ด ์ญ๋ฐฉํฅ ๊ทธ๋ํ์์๋ ๋จ๋ง๋ ธ๋๊ฐ ๋๋ฏ๋ก,
- ์ญ๋ฐฉํฅ ๊ทธ๋ํ์ ๋ํด ๊ฐ์ฅ ๋์ค์ ๋น ์ ธ๋์จ ์ ์ ๋ถํฐ ๋ค์ DFS๋ฅผ ์ ์ฉํ๊ฒ ๋๋ฉด SCC๋ฅผ ๊ตฌํ ์ ์์
- ๋ฐ๋ผ์ O(V + E)์ ์๊ฐ๋ณต์ก๋๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์
5. ์ ์ฒด ์ฝ๋
//MARK: - SCC(Strongly Connected Component) - ์ฝ์ฌ๋ผ์ฃผ ์๊ณ ๋ฆฌ์ฆ(Kosaraju's Algorithm)
//MARK: - Framework
import Foundation
//MARK: - Type
struct Graph {
//MARK: - Property
var edges: [Int]
//MARK: - Init
init() {
self.edges = []
}
}
//MARK: - Variable
var graph: [Graph] = [], reverseGraph: [Graph] = []
var visited: [Bool] = []
var orders: [Int] = [], groups: [Int] = []
var orderCount: Int = 0, groupCount: Int = 0
//MARK: - Function
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)
}
}
orders[orderCount] = x
orderCount += 1
}
func reverseGraphDFS(_ x: Int) -> Void {
visited[x] = true
groups[x] = groupCount
for i in 0..<reverseGraph[x].edges.count {
let y: Int = reverseGraph[x].edges[i]
if !visited[y] {
reverseGraphDFS(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
graph = Array(repeating: Graph(), count: N + 10)
reverseGraph = Array(repeating: Graph(), count: N + 10)
visited = Array(repeating: false, count: N + 10)
orders = Array(repeating: 0, count: N + 10)
groups = Array(repeating: 0, 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)
reverseGraph[b].edges.append(a)
}
//MARK: - Process
for i in stride(from: 1, through: N, by: 1) {
if !visited[i] {
graphDFS(i)
}
}
visited = Array(repeating: false, count: N + 10)
for i in stride(from: orderCount - 1, through: 0, by: -1) {
if !visited[orders[i]] {
reverseGraphDFS(orders[i])
groupCount += 1
}
}
//MARK: - Output
print(groupCount)
}
solution()
์ ์ฒด์ฝ๋๋ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค.