[필수 문제] 깊이우선탐색과 너비우선탐색

2021. 2. 15. 11:37코딩 테스트/필수 문제

1. 문제

그래프가 주어질 때, 0번 정점을 시작으로 하여 깊이우선탐색과 너비우선탐색의 결과를 출력하는 프로그램을 작성하시오. 단, 노드를 방문할 때는 노드 번호가 작은 순서대로 방문한다고 하자.


입력

첫째 줄에 정점의 개수 N과 간선의 개수 M이 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ M ≤ 100,000 ) 둘째 줄부터 간선의 정보가 주어진다. 각 줄은 두 개의 숫자 a, b로 이루어져 있으며, 이는 정점 a와 정점 b가 연결되어 있다는 의미이다. 정점의 번호는 0번부터 N-1번까지이다.

출력

첫 번째 줄에 깊이우선탐색 결과, 두 번째 줄에 너비우선탐색 결과를 출력한다.

예제 입력

9 12
0 1
0 2
0 3
1 5
2 5
3 4
4 5
5 6
5 7
5 8
6 7
7 8

예제 출력

0 1 5 2 4 3 6 7 8
0 1 2 3 5 4 6 7 8

 

 

 

2. 풀이

이 문제의 가장 주의해야할 부분은 입력이다. 예제 입력에서는 순서대로 정점에 대한 정보를 받기 때문에 문제는 없지만, 

 

9 12
0 1
5 6
5 7
0 3
6 7
7 8
1 5
0 2
2 5
3 4
4 5
5 8

 

와 같이 순서가 뒤죽박죽인 경우에는 다른 결과를 출력해낸다. 문제에서처럼 가장 작은 노드 번호 순으로 출력하기 때문에 입력되는 노드의 정보를 정렬하여 문제를 풀어야한다.

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

class Graph {
    private ArrayList<ArrayList<Integer>> graph;

    public Graph(int nodeSize) {
        graph = new ArrayList<>();

        for(int i = 0; i < nodeSize + 1; i++) {
            graph.add(new ArrayList<>());
        }
    }

    public ArrayList<Integer> getNode(int n) {
        return graph.get(n);
    }

    public void put(int n, int m) {
        graph.get(n).add(m);
        graph.get(m).add(n);
    }

    public boolean isAdjacent(int n, int m) {
        for(int i = 0; i < graph.get(n).size(); i++) {
            if(graph.get(n).get(i) == m) return true;
        }
        return false;
    }

    public void graphSort(int n) {
        Collections.sort(graph.get(n));
    }
}

public class Main {

    private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    private static int node;
    private static int edge;

    private static Graph graph;
    private static boolean[] isVisitedDfs;
    private static boolean[] isVisitedBfs;

    public static void main(String[] args) throws IOException {

        StringTokenizer st = new StringTokenizer(br.readLine());
        node = Integer.parseInt(st.nextToken());
        edge = Integer.parseInt(st.nextToken());

        graph = new Graph(node);
        isVisitedDfs = new boolean[node + 1];
        isVisitedBfs = new boolean[node + 1];

        for(int i = 0; i < edge; i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            graph.put(a, b);
        }

        for(int i = 0; i < node; i++) {
            graph.graphSort(i);
        }

        dfs(0);
        System.out.println();
        bfs(0);

        br.close();
    }

    private static void dfs(int v) {
        isVisitedDfs[v] = true;
        System.out.print(v + " ");
        for(int i = 0; i < graph.getNode(v).size(); i++) {
            int w = graph.getNode(v).get(i);
            if(!isVisitedDfs[w]) dfs(w);
        }
    }

    private static void bfs(int v) {
        Queue<Integer> queue = new LinkedList<>();
        queue.add(v);
        isVisitedBfs[v] = true;
        System.out.print(v + " ");

        while(!queue.isEmpty()) {
            int w = queue.poll();

            for(int i = 0; i < node; i++) {
                if(graph.isAdjacent(i, w) && !isVisitedBfs[i]) {
                    queue.add(i);
                    isVisitedBfs[i] = true;
                    System.out.print(i + " ");
                }
            }
        }
    }
}
728x90

'코딩 테스트 > 필수 문제' 카테고리의 다른 글

[필수 문제] 미로 찾기  (0) 2021.02.15
[필수 문제] 전염병  (0) 2021.02.15
[필수 문제] 단지 번호 붙이기  (0) 2021.02.15
[필수 문제] 웜 바이러스  (0) 2021.02.15