Swift Data Structure And Algorithm/Graph Algorithm

ํญ๋ฐœ๋ฌผ ์„ค์น˜

youngjaeLee1026 2022. 4. 18. 17:20

1. ๋ฌธ์ œ

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2022-04-18 17 04 52

2. ์ž…์ถœ๋ ฅ

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2022-04-18 17 05 00

3. ์ž…์ถœ๋ ฅ ์˜ˆ์‹œ

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2022-04-18 17 05 06

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()

 

์ „์ฒด์ฝ”๋“œ๋Š” ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.