[ Baekjoon ] 2026번 ( SILVER III ) : 바이러스 (Java)

ma.caron_g·2022년 5월 10일
0

Class3 - Baekjoon

목록 보기
8/13
post-thumbnail

1. Problem 📃

[ 바이러스 ]

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


[ 문제 ]

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

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

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


2. Input ⌨️

[ 입력 ]

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


3. Output 🖨

[ 출력 ]

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


4. Example 📚

[ 입출력 예시 ]

예제 입력예제 출력
7
6
1 2
2 3
1 5
5 2
5 6
4 7
4

5. Solution 🔑

깊이 우선 탐색(DFS)와 너비 우선 탐색(BFS) 두 가지 방법으로 풀어보았다.
1. 우선 컴퓨터들과 연결 관계 (간선)을 나타내기 위해 2차원 배열(conn)을 선언해주었다.
2. 입력되는 값으로 노드가 연결 돼 있으면 1, 그렇지 않으면 0을 넣어 표시해주었다.
3. 탐색 시 방문했던 노드인지 확인하기 위해 1차원 배열(visited)을 선언해주었다.

[ 1. DFS ]
1-1) 깊이 우선 탐색을 하기 위해 기준이 될 값(standard)을 메서드의 매개변수로 지정해주었다.
1-2) 매개변수에 감염된 컴퓨터를 넣어 매개변수를 기준으로 해당 컴퓨터와 연결돼 있으며, 방문하지 않았던 노드를 찾는다. 찾았다면 해당 노드는 방문했다는 표시를 하고 감염된 컴퓨터 수를 증가시킨다.
1-3) 그 후 해당 노드로 부터 다시 연결된 노드를 찾기위해 메서드를 재호출하여준다.

[ 2. BFS ]
2-1) 너비 우선 탐색을 하기 위해 기준이 될 값(standard)을 메서드의 매개변수로 지정해주었다.
2-2) 큐를 하나 선언하여 최초 감염된 컴퓨터를 넣어준다.
2-3) 큐가 빌 때 까지 큐에 들어있던 최초 감염 컴퓨터를 뽑아 그 컴퓨터를 기준으로 해당 컴퓨터와 연결돼 있으며, 방문하지 않았던 노드를 찾는다. 찾았다면 연결되어 있는 해당 컴퓨터를 모두 넣어준다.
2-4) 다 탐색했다면 큐에 들어있는 다음 노드를 기준으로 연결되어 있으며, 방문하지 않았던 노드를 찾아 위 과정을 큐가 비어있을 때까지 반복하여 노드를 탐색한다.

6. Code 💻

[ 깊이 우선 탐색 (DFS) ]

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

	private static int[][] conn;
	private static boolean[] visited;
	private static int infected = 0;
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		
		int N = Integer.parseInt(st.nextToken());
		st = new StringTokenizer(br.readLine(), " ");
		int C = Integer.parseInt(st.nextToken());
		int x, y;
		
		conn = new int[N+1][N+1];
		visited = new boolean[N+1];
		visited[1] = true;
		
		
		
		for(int i=0; i<C; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			x = Integer.parseInt(st.nextToken());
			y = Integer.parseInt(st.nextToken());
			conn[x][y] = 1;
			conn[y][x] = 1;
		}
		
		DFS(1);
		System.out.println(infected);

	}
	
	private static void DFS(int standard) {
		
		for(int i=1; i<conn.length; i++) {	
			if(conn[standard][i] == 1 && visited[i] == false) {
				visited[i] = true;
				infected++;
				DFS(i);
			}
		}
	}

}

[ 너비 우선 탐색 (BFS) ]

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

	private static int[][] conn;
	private static boolean[] visited;
	private static int infected = 0;
	static Queue<Integer> q = new LinkedList<Integer>();
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		
		int N = Integer.parseInt(st.nextToken());
		st = new StringTokenizer(br.readLine(), " ");
		int C = Integer.parseInt(st.nextToken());
		int x, y;
		
		conn = new int[N+1][N+1];
		visited = new boolean[N+1];
		visited[1] = true;
		
		
		
		for(int i=0; i<C; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			x = Integer.parseInt(st.nextToken());
			y = Integer.parseInt(st.nextToken());
			conn[x][y] = 1;
			conn[y][x] = 1;
		}
		
		BFS(1);
		System.out.println(infected);

	}
	
	private static void BFS(int standard) {
		
		q.offer(standard);
		
		while(!q.isEmpty()) {
			
			int val = q.poll();
			
			System.out.println(q);
			
			for(int i=1; i<conn.length; i++) {
				
				System.out.println(q + " i : " + i);
				if(conn[val][i] == 1 && visited[i] == false) {
					q.offer(i);
					visited[i] = true;
					infected++;
				}
			}
		}
	}

}

7. Growth 🍄

[ 깊이 우선 탐색 ] 재귀함수 사용
[ 너비 우선 탐색 ] 재귀함수를 사용 X
profile
다른 사람이 만든 것을 소비하는 활동보다, 내가 생산적인 활동을 하는 시간이 더 많도록 생활화 하자.

0개의 댓글