youngjaeLee1026 2022. 4. 18. 17:14

1. ๋ฌธ์ œ

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

2. ์ž…์ถœ๋ ฅ

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

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

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

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

 

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