[백준] 2606 바이러스(실버3) - 그래프(DFS)

2024. 7. 3. 03:31·코딩 테스트/자료구조

문제

코드

시도1 - 인접 행렬O

이번 문제는 특정 노드에 연결된 노드들을 탐색하는 것이 핵심이다.
인접 행렬과 인접 리스트 모두 가능한데 우선 인접 행렬을 이용하여 구현해봤다.

  1. 2차원 배열로 정점간의 연결 유무를 구현한다.
  2. DFS를 이용하여 특정 정점(target)과 연결된 정점을 찾고 HashSet에 저장한다.
    • 연결된 정점이 HashSet에 존재하지 않다면 연결된 정점을 target으로 DFS를 실행한다.
      사실 DFS는 생각하지 못했고 재귀만 생각하고 풀었는데 풀고 살펴보니 DFS를 이용한 풀이였다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.StringTokenizer;

public class _2606 {
    static int[][] graph;
    static HashSet<Integer> hs = new HashSet<>();
    public static void main(String [] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int vertexCnt = Integer.parseInt(br.readLine());
        int edgeCnt = Integer.parseInt(br.readLine());

        // 인접 행렬 그래프: 탐색이 핵심이기 때문에 인접 리스트가 아닌 인접 행렬을 이용해 구현
        graph = new int[vertexCnt+1][vertexCnt+1];
        for (int i = 0; i < edgeCnt; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int vertex1 = Integer.parseInt(st.nextToken());
            int vertex2 = Integer.parseInt(st.nextToken());

            graph[vertex1][vertex2] = 1;
            graph[vertex2][vertex1] = 1;
        }

        hs.add(1);
        search(1);

        // 아래 코드처럼 1에 연결된 노드들을 먼저 해시에 넣고 시작하면 시간이 더 적게 걸림..
//        for (int i = 0; i < graph[1].length; i++) {
//            if (graph[1][i] == 1 && !hs.contains(i)) {
//                hs.add(i);
//                search(i);
//            }
//        }
        System.out.println(hs.size()-1);


    }

    public static void search(int target) {
        for (int i = 0; i < graph[target].length; i++) {
            if (graph[target][i] == 1 && !hs.contains(i)) {
                hs.add(i);
                search(i);
            }
        }
    }
}

 

 

시도2 - 인접 리스트O

인접 리스트를 이용하여 그래프를 구현한 코드이다. 코드 구성은 로직1과 같다. 다만 인접 행렬 방식은 모든 노드와 연결 여부를 확인해야 하는 반면 인접 리스트는 에초에 연결된 노드들만 리스트에 저장하기 때문에 다른 노드와 연결 여부를 확인하지 않는다.

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

public class _2606 {
    static ArrayList<ArrayList<Integer>> graph;
    static boolean[] visited;
    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<>();
        for (int i = 0; i <= n; i++) {
            graph.add(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.get(a).add(b);
            graph.get(b).add(a);
        }

        visited = new boolean[n + 1];

        dfs(1); // 1번 컴퓨터부터 시작

        System.out.println(count - 1); // 1번 컴퓨터 제외
    }

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

        for (int i : graph.get(v)) {
            if (!visited[i]) {
                dfs(i);
            }
        }
    }
}

 

1년 전 풀이 - O

아래 코드는 1년 전 내가 작성한 코드이다. 시도1과 코드 구성은 똑같지만 HashMap이 아닌 배열을 이용하여 풀었다.

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class _2606 {
    public static boolean [] visited;
    public static int[][] arrGraph;
    public static int num;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st;

        int n = Integer.parseInt(br.readLine());
        int pair = Integer.parseInt(br.readLine());

        // arrGraph 초기화
       arrGraph = new int[n+1][n+1];
        visited = new boolean[n+1];
        Arrays.fill(visited, false);

        for (int i = 0; i < pair; i++) {
            int n1, n2;
            st = new StringTokenizer(br.readLine(), " ");
            n1 = Integer.parseInt(st.nextToken());
            n2 = Integer.parseInt(st.nextToken());
            // n1*n2 = 1 삽입(연결된다는 뜻)
            arrGraph[n1][n2] = arrGraph[n2][n1]= 1;
        }
        dfs(1, n);
        // 1번 컴퓨터는 뺴야 하니깐 num-1
        System.out.println(num-1);
    }
    // 재귀를 이용한 dfs
    public static void dfs(int node, int n) {
        visited[node] = true; // 현재 노드(1) 방문 처리
        num += 1; // 감염된 컴퓨터 추가
        // node번쨰 행을 돌면서 연결된 노드가 있는지 확인
        // 연결된 노드가 있다면 그 노드로 가서(연결된 노드의 행으로 가서) 연결된 노드가 있는지 확인
        // 만약 연결된 노드가 없다면 함수가 종료되면서 바로 전 노드로 돌아옴
        int k = 0;
        for (int i = 1; i <= n; i++) {
            // 이후 노드에 방문하지 않았다면
            if (arrGraph[node][i] == 1 && visited[i] == false)
                dfs(i, n);
        }
    }
}

 

'코딩 테스트 > 자료구조' 카테고리의 다른 글

[프로그래머스] 49189 가장 먼 노드(Level3) - 그래프, BFS  (0) 2024.07.05
[백준] 2178 미로 탐색(실버1) - 그래프  (0) 2024.07.04
[백준] 2841 외계인의 기타 연주(실버1) - 스택  (0) 2024.07.01
[백준] 1966 프린터 큐(실버3) - 큐(Queue)  (0) 2024.07.01
[프로그래머스] 42584 주식가격(Lv2) - 스택  (0) 2024.06.30
'코딩 테스트/자료구조' 카테고리의 다른 글
  • [프로그래머스] 49189 가장 먼 노드(Level3) - 그래프, BFS
  • [백준] 2178 미로 탐색(실버1) - 그래프
  • [백준] 2841 외계인의 기타 연주(실버1) - 스택
  • [백준] 1966 프린터 큐(실버3) - 큐(Queue)
토자맨
토자맨
  • 토자맨
    개발하는 토자맨
    토자맨
  • 전체
    오늘
    어제
    • 개발 공부
      • 코딩 테스트
        • 코드업 기초 100제
        • 백준
        • 99클럽
        • 자료구조
        • 알고리즘
      • Programming Language
        • 자바(JAVA)
      • Back-end
        • Spring
      • Front-end
        • html
        • css
      • DevOps
        • AWS
        • CI CD
        • Docker
        • 홈서버
        • Git
      • Computer Science
        • 자료구조
        • 알고리즘
        • 운영체제
        • OS,Network,DB,DesignPattern
      • 프로젝트
        • 웨이트 쇼핑몰
      • 공부 로드맵
        • 2학년 겨울방학
        • 3학년 2학기
        • 3학년 겨울방학
      • 일상
        • 기타 정보
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    프로그래머스 #dp
    백준 #dfs #11725번
    백준 #이진탐색 #이분탐색
    스프링 #spring #스프링 컨테이너 #스프링 컨텍스트
    bfs #최단거리탐색 #프로그래머스
    bfs #백준
    ec2 멈춤 #ec2 터짐 #ec2 ssh 연결 끊김 #ec2 끊김
    dp #백준 #동적계획법
    dfs #알고리즘
    99클럽 #코딩테스트 준비 #개발자 취업 #항해99 #til
    백준 #아기상어2 #bfs
    피보나치 수 #백준 #dp
    dfs #백준
    git filter-repo
    싱글톤 패턴 #싱글톤 컨테이너 #싱글톤 레지스트리 #싱글톤 객체 상태 #무상태 #stateless #유지상태 #staleful
    백준 #dfs #알고리즘
    nvidia-docker #docker cuda #docker gpu #엔비디아 도커
    nvidia container toolkit #
    오블완
    백준 #dp #동적계획법
    이진탐색 #이분탐색 #백준
    티스토리챌린지
    백준 #dfs
    이진탐색 #이분탐색 #알고리즘
    git filter-branch #commit 수정 #commit
    solid #객체지향설계원칙
    bfs #프로그래머스
    프로그래머스 #dfs
    백준 #bfs
    스프링핵심원리 #김영한 #의존관계자동주입 #의존관계 자동 주입
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
토자맨
[백준] 2606 바이러스(실버3) - 그래프(DFS)
상단으로

티스토리툴바