전체 방문자
오늘
어제
모달조아
Better than yesterday
모달조아
  • 분류 전체보기 (147)
    • PS (86)
      • BOJ (79)
      • 프로그래머스 (6)
    • 이론 (41)
      • 자료구조 (2)
      • 알고리즘 (8)
      • 데이터베이스 (1)
      • 운영체제 (1)
      • 네트워크 (3)
      • 디자인패턴 (7)
      • Java (13)
      • Spring (4)
      • JPA (1)
      • Git (1)
    • 개발 (18)
    • 프로젝트 (1)
    • 기록 (0)
      • 후기 (0)
    • etc (1)

최근 글

티스토리

hELLO · Designed By 정상우.
모달조아

Better than yesterday

PS/BOJ

BOJ 1260 DFS와 BFS [Java]

2022. 1. 31. 01:21

BOJ 1260 DFS와 BFS

1. 문제 링크

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

2. 문제 해설

그래프에서의 dfs와 bfs를 할 수 있는지를 묻는 문제이다. 인접 리스트를 이용하여 그래프를 표현해주고 dfs와 bfs를 돌려주면 된다.

주의할 점
1. 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문한다는 점이다.
: 인접 리스트에서 각 정점의 원소들을 오름차순으로 정렬해주면 쉽게 해결할 수 있다.

2. dfs를 비재귀적인 방식으로 풀 경우 재귀적인 dfs와 방문 순서가 다를 수 있다.
: 나는 dfs를 재귀적인 방식으로 풀었지만, 재귀적인 방식이 아닌 stack을 이용해서 풀 경우 방문 처리를 제대로 해주지않으면 재귀적인 방식과 방문 순서가 달라지게 될 수 있다. 내가 bfs에서 큐에 넣을 때 vis[nxt]를 true로 처리한 것과 같은 방식으로 스택에 넣을 때 방문을 했다고 처리하면 안된다.
재귀적인 방식은 실제 방문을 할 때 방문 표시를 남기는 반면에 비재귀적인 방식은 방문하기 전에 아직 방문하지 않은 곳을 발견하면 그 때 방문 표시를 남겨버리기 때문에 이러한 차이가 발생한다. 그렇다면 stack을 이용해서 어떻게 재귀적인 방식처럼 동작하도록 할 수 있을까?

static void dfs() {
        sta.add(v);
        vis = new boolean[n];

        while (!sta.isEmpty()) {
            int cur = sta.pop();

            if (vis[cur]) {
                continue;
            }

            vis[cur] = true;
            sb.append(cur + 1).append(' ');

            for (int i = 0; i < adj.get(cur).size(); i++) {
                int nxt = adj.get(cur).get(adj.get(cur).size() - 1 - i);

                if (vis[nxt]) {
                    continue;
                }

                sta.add(nxt);
            }
        }

        sb.append('\n');
    }

위와 같이 스택에서 뺄 때 방문을 했다고 처리하면 재귀적인 dfs와 방문 순서가 동일하다. 다만 이렇게 하면 스택에 같은 정점의 값이 여러 번 들어갈 수 있지만, 8~10줄 코드를 통해 각 정점마다 연결된 정점을 보는 작업은 1번씩만 하도록 처리해놓아서 시간복잡도는 동일하게 유지할 수 있다.
16번째 줄은 스택에서 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문한다는 법칙을 지켜주기위해 저렇게 처리하였다.

3. 코드 보기

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

public class Main {
    static StringBuilder sb;
    static int n;
    static int m;
    static int v;
    static boolean[] vis;
    static ArrayList<ArrayList<Integer>> adj;
    static Queue<Integer> q;

    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 = new StringTokenizer(br.readLine());
        sb = new StringBuilder();

        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        v = Integer.parseInt(st.nextToken()) - 1;
        vis = new boolean[n];
        adj = new ArrayList<>();
        q = new LinkedList<>();

        for (int i = 0; i < n; i++) {
            adj.add(new ArrayList<>());
        }

        for (int i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(st.nextToken()) - 1;
            int to = Integer.parseInt(st.nextToken()) - 1;

            adj.get(from).add(to);
            adj.get(to).add(from);
        }

        for (int i = 0; i < n; i++) {
            Collections.sort(adj.get(i));
        }

        dfs(v);
        bfs();

        bw.write(sb.toString());
        br.close();
        bw.flush();
        bw.close();
    }

    static void dfs(int idx) {
        if (idx == n) {
            return;
        }

        vis[idx] = true;
        sb.append(idx + 1).append(' ');

        for (int i = 0; i < adj.get(idx).size(); i++) {
            int nxt = adj.get(idx).get(i);

            if (vis[nxt]) {
                continue;
            }

            dfs(nxt);
        }
    }

    static void bfs() {
        sb.append('\n');
        q.add(v);
        vis = new boolean[n];
        vis[v] = true;

        while (!q.isEmpty()) {
            int cur = q.poll();
            sb.append(cur + 1).append(' ');

            for (int i = 0; i < adj.get(cur).size(); i++) {
                int nxt = adj.get(cur).get(i);

                if (vis[nxt]) {
                    continue;
                }

                q.add(nxt);
                vis[nxt] = true;
            }
        }
    }
}
저작자표시 (새창열림)

'PS > BOJ' 카테고리의 다른 글

BOJ 11559 Puyo Puyo [Java]  (0) 2022.02.09
BOJ 15686 치킨 배달 [Java]  (0) 2022.02.01
BOJ 2004 조합 0의 개수 [Java]  (0) 2022.01.26
BOJ 1676 팩토리얼 0의 개수 [Java]  (0) 2022.01.26
BOJ 1149 RGB거리 [Java]  (0) 2022.01.07
    'PS/BOJ' 카테고리의 다른 글
    • BOJ 11559 Puyo Puyo [Java]
    • BOJ 15686 치킨 배달 [Java]
    • BOJ 2004 조합 0의 개수 [Java]
    • BOJ 1676 팩토리얼 0의 개수 [Java]
    모달조아
    모달조아

    티스토리툴바