240215 TIL #322 CT_바이러스(BFS)

김춘복·2024년 2월 14일
0

TIL : Today I Learned

목록 보기
322/494

Today I Learned

오늘도 백준에서 코테!


바이러스

https://www.acmicpc.net/problem/2606

문제

신종 바이러스인 웜 바이러스는 네트워크를 통해 전파된다. 한 컴퓨터가 웜 바이러스에 걸리면 그 컴퓨터와 네트워크 상에서 연결되어 있는 모든 컴퓨터는 웜 바이러스에 걸리게 된다.
예를 들어 7대의 컴퓨터가 <그림 1>과 같이 네트워크 상에서 연결되어 있다고 하자. 1번 컴퓨터가 웜 바이러스에 걸리면 웜 바이러스는 2번과 5번 컴퓨터를 거쳐 3번과 6번 컴퓨터까지 전파되어 2, 3, 5, 6 네 대의 컴퓨터는 웜 바이러스에 걸리게 된다. 하지만 4번과 7번 컴퓨터는 1번 컴퓨터와 네트워크상에서 연결되어 있지 않기 때문에 영향을 받지 않는다.
어느 날 1번 컴퓨터가 웜 바이러스에 걸렸다. 컴퓨터의 수와 네트워크 상에서 서로 연결되어 있는 정보가 주어질 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 출력하는 프로그램을 작성하시오.

입력 : 첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하인 양의 정수이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어진다. 이어서 그 수만큼 한 줄에 한 쌍씩 네트워크 상에서 직접 연결되어 있는 컴퓨터의 번호 쌍이 주어진다.

7
6
1 2
2 3
1 5
5 2
5 6
4 7

출력 : 1번 컴퓨터가 웜 바이러스에 걸렸을 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 첫째 줄에 출력한다.


풀이과정

  • 백트래킹으로 간단하게 풀 수 있는 문제다. 코틀린으로 bfs를 구현해 해결했다.
  1. 입력을 readln().toInt()로 받아준다.

  2. 그래프를 2중리스트로 구현한다. 0번째는 비워두기 위해 n+1만큼 내부 리스트를 선언해둔다.

  3. 이어지는 입력을 readln().split(" ").map { it.toInt() }로 받아준다. 양방향 리스트를 구현한다. 코틀린에서는 graph[a]와 같이 표현해도 인식이 바로 된다. .get()을 쓸 필요가 없다.

  4. Boolean 배열을 체크용으로 선언해둔다.

  5. 확실히 구분하기 위해 bfs 함수를 따로 만든다. 큐를 구현해서 bfs를 마저 구현한다. count 변수를 하나 만들어 방문하지 않았던 노드들을 방문하면서 카운트를 늘린다.

  6. 1번 컴퓨터를 통해 바이러스에 걸리는 컴퓨터 수를 구해야 하므로 1번 컴퓨터는 빼야하니 -1 을 해준채로 반환을 해주면 완료!


Kotlin 코드

import java.util.LinkedList
import java.util.Queue

fun main() {
    val n = readln().toInt()
    val m = readln().toInt()
    val graph = ArrayList<ArrayList<Int>>()

    repeat(n+1){
        graph.add(ArrayList())
    }

    repeat(m){
        val (a, b) = readln().split(" ").map { it.toInt() }
        graph[a].add(b)
        graph[b].add(a)
    }

    val check = BooleanArray(n+1)
    check[0] = true

    print(bfs(1, check, graph))
}

fun bfs(start: Int, check: BooleanArray, graph: ArrayList<ArrayList<Int>>): Int{
    check[start] = true
    val queue:Queue<Int> = LinkedList()
    var count = 0

    queue.add(start)
    check[start] = true

    while (queue.isNotEmpty()){
        val n = queue.poll()
        count++

        for (nextNode in graph[n]){
            if (!check[nextNode]){
                queue.add(nextNode)
                check[nextNode] = true
            }
        }
    }

    return count -1
}
profile
꾸준히 성장하기 위해 매일 log를 남깁니다!

0개의 댓글