공log/[P&B]

[P&B] #106 BAEKJOON 2606

ming_OoO 2023. 10. 1. 22:53
728x90

백준 2606번 바이러스 JAVA

문제 설명

신종 바이러스인 웜 바이러스는 네트워크를 통해 전파된다. 한 컴퓨터가 웜 바이러스에 걸리면 그 컴퓨터와 네트워크 상에서 연결되어 있는 모든 컴퓨터는 웜 바이러스에 걸리게 된다.

예를 들어 7대의 컴퓨터가 <그림 1>과 같이 네트워크 상에서 연결되어 있다고 하자. 1번 컴퓨터가 웜 바이러스에 걸리면 웜 바이러스는 2번과 5번 컴퓨터를 거쳐 3번과 6번 컴퓨터까지 전파되어 2, 3, 5, 6 네 대의 컴퓨터는 웜 바이러스에 걸리게 된다. 하지만 4번과 7번 컴퓨터는 1번 컴퓨터와 네트워크상에서 연결되어 있지 않기 때문에 영향을 받지 않는다.

어느 날 1번 컴퓨터가 웜 바이러스에 걸렸다. 컴퓨터의 수와 네트워크 상에서 서로 연결되어 있는 정보가 주어질 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 출력하는 프로그램을 작성하시오.

 

입력

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

 

출력

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

 

나의 문제 풀이 코드

import java.util.*;
import java.io.*;

public class bj2606 {
    static boolean[] visited;
    static ArrayList<Integer>[] graph;
    static int count = 0;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine()); // 컴퓨터의 수
        int m = Integer.parseInt(br.readLine()); // 직접 연결된 컴퓨터 쌍의 수

        // 그래프 초기화
        graph = new ArrayList[n + 1];
        for (int i = 1; i <= n; i++) {
            graph[i] = new ArrayList<>();
        }

        // 그래프 정보 입력
        for (int i = 0; i < m; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            graph[a].add(b);
            graph[b].add(a); // 무방향 그래프이므로 양방향으로 추가
        }

        visited = new boolean[n + 1];
        dfs(1); // 1번 컴퓨터부터 시작

        // 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수 출력 (1은 제외)
        System.out.println(count-1);
    }

    public static void dfs(int node) {
        visited[node] = true;
        count++;

        for (int neighbor : graph[node]) {
            if (!visited[neighbor]) {
                dfs(neighbor);
            }
        }
    }
}

 

문제 풀이 코멘트

그래프의 개념

그래프(Graph)는 현실 세계의 객체 또는 개념 간의 연결 관계를 표현하는 자료 구조입니다. 그래프는 실제로 네트워크, 도로망, 소셜 네트워크, 컴퓨터 네트워크 등 다양한 분야에서 활용됩니다. 그래프는 정점(Vertex)과 간선(Edge)의 집합으로 구성되며, 정점은 객체나 개념을 나타내고, 간선은 정점 간의 연결 관계를 나타냅니다. 그래프는 다양한 형태로 나타날 수 있으며, 실제로 많은 문제와 애플리케이션에서 활용됩니다. 

 

정점(Vertex): 그래프를 구성하는 핵심 요소로, 객체나 개념을 나타냅니다. 정점은 종종 노드(Node)라고도 부릅니다.

간선(Edge): 정점 간의 연결 관계를 나타내며, 두 정점을 연결하는 선입니다. 간선은 방향 그래프(Directed Graph)와 무방향 그래프(Undirected Graph)로 나뉩니다.

방향 그래프(Directed Graph): 간선에 방향이 존재하여 한 정점에서 다른 정점으로의 방향성이 있는 그래프를 말합니다.

무방향 그래프(Undirected Graph): 간선에 방향이 없어 양쪽으로 연결된 그래프를 말합니다.

가중 그래프(Weighted Graph): 간선에 가중치(weight)가 부여된 그래프로, 간선을 통과하는 비용이나 거리 등을 나타낼 때 사용됩니다.

부분 그래프(Subgraph): 기존 그래프에서 일부 정점과 간선으로 이루어진 그래프를 의미합니다.

연결 그래프(Connected Graph): 모든 정점 쌍 간에 최소 하나의 경로가 존재하는 그래프를 의미합니다.

트리(Tree): 사이클이 없는 연결 그래프로, 모든 정점이 서로 연결되어 있으며, 트리에서 한 정점을 루트(root)라고 부릅니다.

이 문제에서는 무방향 그래프를 사용합니다. 각 컴퓨터는 그래프의 노드이며, 연결 정보를 통해 노드 간의 간선을 표현합니다.

문제 해결 방법

주어진 문제는 1번 컴퓨터를 시작으로 웜 바이러스에 걸리게 되는 컴퓨터의 수를 구하는 것입니다. 이것은 그래프의 연결된 구성 요소(Connected Component)를 찾는 문제로, 깊이 우선 탐색(DFS) 또는 너비 우선 탐색(BFS) 알고리즘을 활용할 수 있습니다. 이번에는 깊이 우선 탐색(DFS)을 사용하여 문제를 해결했습니다.
깊이 우선 탐색(DFS)은 그래프나 트리에서 정점을 탐색하는 알고리즘 중 하나입니다. DFS는 이름 그대로 가능한 깊숙이 들어가서 정점을 방문하며, 그래프의 모든 정점을 탐색하는 방법 중 하나입니다.
시작 정점에서 출발하여 다음 정점을 선택하고, 선택한 정점에서 다시 다음 정점을 선택하는 식으로 깊이 우선으로 탐색합니다.
더 이상 탐색할 수 있는 정점이 없으면 이전 정점으로 돌아가서 다른 경로로 탐색을 계속합니다.
정점을 방문할 때, 해당 정점이 이미 방문한 정점인지 여부를 확인하여 중복 방문을 피합니다.
스택(Stack)이나 재귀 함수를 사용하여 구현할 수 있습니다.
DFS는 그래프의 연결 여부, 경로 탐색, 사이클 검출, 특정 정점에 대한 탐색 등 다양한 그래프 문제를 해결하는 데 사용됩니다. 또한, DFS는 트리 구조에서도 사용되어 트리의 순회(Traversal)를 수행하며 원하는 정보를 찾는 데 활용됩니다.

 

웜 바이러스 전파 문제에서는 1번 컴퓨터부터 시작하여 연결된 모든 컴퓨터를 방문하면 됩니다.

  1. 그래프를 인접 리스트로 표현하기 위해 ArrayList<Integer>[] graph를 사용합니다.
  2. 그래프 정보를 입력받고, 무방향 그래프이므로 양방향으로 간선을 추가합니다.
  3. 방문 여부를 나타내는 visited 배열을 사용하여 DFS를 구현합니다. dfs 함수는 시작 노드부터 깊이 우선 탐색을 진행하며, 방문한 노드의 수를 카운트합니다.
  4. 1번 컴퓨터를 시작으로 DFS를 호출하여 웜 바이러스에 걸리게 되는 컴퓨터의 수를 구합니다.
  5. 마지막으로 구해진 수는 1번 컴퓨터를 포함한 컴퓨터의 수이기 때문에 1을 차감한 값을 출력합니다.
728x90

'공log > [P&B]' 카테고리의 다른 글

[P&B] #108 BAEKJOON 2346  (0) 2023.10.02
[P&B] #107 BAEKJOON 12789  (1) 2023.10.02
[P&B] #105 BAEKJOON 9095  (0) 2023.10.01
[P&B] #104 BAEKJOON 1463  (0) 2023.10.01
[P&B] #103 BAEKJOON 9375  (0) 2023.10.01