문제
문제
신종 바이러스인 웜 바이러스는 네트워크를 통해 전파된다. 한 컴퓨터가 웜 바이러스에 걸리면 그 컴퓨터와 네트워크 상에서 연결되어 있는 모든 컴퓨터는 웜 바이러스에 걸리게 된다.
예를 들어 7대의 컴퓨터가 <그림 1>과 같이 네트워크 상에서 연결되어 있다고 하자. 1번 컴퓨터가 웜 바이러스에 걸리면 웜 바이러스는 2번과 5번 컴퓨터를 거쳐 3번과 6번 컴퓨터까지 전파되어 2, 3, 5, 6 네 대의 컴퓨터는 웜 바이러스에 걸리게 된다. 하지만 4번과 7번 컴퓨터는 1번 컴퓨터와 네트워크상에서 연결되어 있지 않기 때문에 영향을 받지 않는다.
어느 날 1번 컴퓨터가 웜 바이러스에 걸렸다. 컴퓨터의 수와 네트워크 상에서 서로 연결되어 있는 정보가 주어질 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 출력하는 프로그램을 작성하시오.
입력
첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하인 양의 정수이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어진다. 이어서 그 수만큼 한 줄에 한 쌍씩 네트워크 상에서 직접 연결되어 있는 컴퓨터의 번호 쌍이 주어진다.
출력
1번 컴퓨터가 웜 바이러스에 걸렸을 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 첫째 줄에 출력한다.
입출력예시
풀이
💡 방법1 ➡️ 인접행렬 사용한 DFS
import java.util.Scanner;
public class Main {
static int N, E, count;
static int[] ch;
static int[][] graph;
public static void DFS(int v) {
for(int i=1; i<N+1; i++) {
if(graph[v][i]==1 && ch[i]==0) {
count++;
ch[i]=1;
DFS(i);
}
}
}
/*
public static void DFS2(int v) {
ch[v]=1;
for(int i=1; i<N+1; i++) {
if(graph[v][i]==1 && ch[i]==0) {
count++;
DFS(i);
}
}
}
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
graph = new int[N+1][N+1];
ch = new int[N+1];
E = sc.nextInt();
for(int i=0; i<E; i++) {
int s = sc.nextInt();
int e = sc.nextInt();
graph[s][e] = graph[e][s] = 1;
}
ch[1]=1; //생략하면 DFS2함수 사용가능
Main.DFS(1);
System.out.println(count);
}
}
💡 방법2 ➡️ 인접행렬 사용한 BFS
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static int N, E, count;
static int[] ch;
static int[][] graph;
public static void BFS(int v) {
Queue<Integer> Q = new LinkedList<>();
ch[v]=1;
Q.offer(v);
while(!Q.isEmpty()) {
int tmp = Q.poll();
for(int j=0; j<N+1; j++) {
if(graph[tmp][j]==1 && ch[j]==0) {
count++;
ch[j]=1;
Q.offer(j);
}
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
graph = new int[N+1][N+1];
ch = new int[N+1];
E = sc.nextInt();
for(int i=0; i<E; i++) {
int s = sc.nextInt();
int e = sc.nextInt();
graph[s][e] = graph[e][s] = 1;
}
Main.BFS(1);
System.out.println(count);
}
}
💡 방법3 ➡️ 인접리스트 사용한 DFS
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
static int N, E, count;
static int[] ch;
static ArrayList<ArrayList<Integer>> graph;
public static void DFS(int v){
for(int nv : graph.get(v)) {
if(ch[nv]==0) {
ch[nv]=1;
count++;
DFS(nv);
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
graph = new ArrayList<>();
for(int i=0; i<N+1; i++) {
graph.add(new ArrayList<>());
}
ch = new int[N+1];
E = sc.nextInt();
for(int i=0; i<E; i++) {
int s = sc.nextInt();
int e = sc.nextInt();
graph.get(s).add(e);
graph.get(e).add(s);
}
ch[1]=1;
Main.DFS(1);
System.out.println(count);
}
}
💡 방법4 ➡️ 인접리스트 사용한 BFS
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static int N, E, count;
static int[] ch;
static ArrayList<ArrayList<Integer>> graph;
public static void BFS(int v){
Queue<Integer> Q = new LinkedList<>();
Q.offer(v);
while(!Q.isEmpty()) {
int cv = Q.poll();
for(int nv : graph.get(cv)) {
if(ch[nv]==0) {
ch[nv]=1;
count++;
Q.offer(nv);
}
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
graph = new ArrayList<>();
for(int i=0; i<N+1; i++) {
graph.add(new ArrayList<>());
}
ch = new int[N+1];
E = sc.nextInt();
for(int i=0; i<E; i++) {
int s = sc.nextInt();
int e = sc.nextInt();
graph.get(s).add(e);
graph.get(e).add(s);
}
ch[1]=1;
Main.BFS(1);
System.out.println(count);
}
}
느낀점
1. 무방향 그래프는 무조건 양쪽 방향을 모두 생각해야 한다.
인접행렬을 사용할 때에는
graph[s][e] = graph[e][s] = 1; 처럼 연결된 정보들을 양방향으로 넣어주어야 하고
인접리스트를 사용할 때에는
graph.get(s).add(e);
graph.get(e).add(s); 처럼 연결 정보를 양쪽으로 입력해준다.
그 이유는 "무방향그래프"이기 때문에 2 - 3 연결정보가 주어진 경우
노드 2 -> 노드 3으로 이동도 가능하고 노드 3 -> 노드 2로도 이동이 가능하기 때문에 양쪽 모두 고려해주어야 한다.
2. 이중 ArrayList의 다른 사용법 발견
기존에 사용했던 방법
선언
ArrayList<ArrayList<Integer>> graph;
초기화
for(int i=0; i<N+1; i++) {
graph.add(new ArrayList<Integer>());
}
값 삽입
graph.get(a).add(b);
새로 발견한 방법
선언
ArrayList<Integer>[] graph;
초기화
for(int i=0; i<N+1; i++){
graph[i] = new ArrayList<>();
}
값 삽입
graph[a].add(b);
'Algorithm > 백준' 카테고리의 다른 글
[백준/JAVA] 🥈 1260번 DFS와 BFS (0) | 2023.12.02 |
---|---|
[백준/JAVA] 🥇 14502번 연구소 (0) | 2023.11.27 |
[백준/JAVA] 🥈 1012번 유기농 배추 (1) | 2023.11.25 |
[백준] error: illegal character: '\u0008' 해결 방법 (1) | 2023.11.25 |
[백준] error: class ex is public, should be declared in a file named ex.java 해결 방법 (0) | 2023.11.25 |