๊ธฐ๋ก๋ฐฉ

BOJ_9466 : ํ…€ ํ”„๋กœ์ ํŠธ ๋ณธ๋ฌธ

CodingTest/Java

BOJ_9466 : ํ…€ ํ”„๋กœ์ ํŠธ

Soom_1n 2024. 5. 23. 17:48

๐Ÿ‘‰ ๋ฌธ์ œ๋งํฌ



๐Ÿ”ธ ๋ฌธ์ œ ๋ถ„์„ ๐Ÿ”ธ

  • T๋ฒˆ์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์•ˆ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž…๋ ฅ์ด ์ฃผ์–ด์ง„๋‹ค.
  • n๋ช… (2~10๋งŒ)์˜ ํ•™์ƒ ์ˆ˜๊ฐ€ ์ฃผ์–ด์ง€๊ณ , ๋‹ค์Œ ์ค„์— ๊ฐ ํ•™์ƒ์ด ๊ฐ™์ด ํŒ€์„ ํ•˜๊ณ  ์‹ถ์€ ํ•™์ƒ์˜ ๋ฒˆํ˜ธ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค.
  • ์ž๊ธฐ ์ž์‹ ์„ ๋ฝ‘๊ฑฐ๋‚˜, ํŒ€์„ ํ•˜๊ณ ์‹ถ์€ ํ•™์ƒ๋“ค๋ผ๋ฆฌ ์ˆœํ™˜๊ตฌ์กฐ(์„œํด)์ด ๋งŒ๋“ค์–ด์ง€๋ฉด ํŒ€์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • ์ตœ์ข…์ ์œผ๋กœ ํŒ€์— ์†ํ•˜์ง€ ์•Š์€ ํ•™์ƒ์˜ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

๐Ÿ”ธ ๋ฌธ์ œ ํ’€์ด ๐Ÿ”ธ

  1. ์ œํ•œ์‹œ๊ฐ„ 3์ดˆ์— ๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ n์ด 10๋งŒ์ด๊ธฐ ๋•Œ๋ฌธ์— O(n^2)์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
  2. ํŒ€์ด ๋งŒ๋“ค์–ด์ง€๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰(DFS)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  3. DFS์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    1. 1) ํƒ์ƒ‰ํ•˜๋‹ค๊ฐ€ ์‹œ์ž‘ ๋ฒˆํ˜ธ๋ฅผ ๋‹ค์‹œ ์ฐพ์Œ : ํƒ์ƒ‰ํ•œ ๋ชจ๋“  ํ•™์ƒ๋“ค์€ ๊ฐ™์€ ํŒ€
    2. 2) ํƒ์ƒ‰ํ•˜๋‹ค๊ฐ€ ์ค‘๊ฐ„ ๋ฒˆํ˜ธ๋ฅผ ๋‹ค์‹œ ์ฐพ์Œ : ์ค‘๊ฐ„ ๋ฒˆํ˜ธ๊นŒ์ง€ ํŒ€์ด๊ณ , ์‹œ์ž‘ ๋ฒˆํ˜ธ๋ถ€ํ„ฐ ์ค‘๊ฐ„ ๋ฒˆํ˜ธ ์‚ฌ์ด๋Š” ํŒ€์„ ๋งŒ๋“ค ์ˆ˜ ์—†์Œ
    3. 3) ์ด๋ฏธ ํŒ€ ์†Œ์†์ด ์žˆ๋Š” ๋ฒˆํ˜ธ : ์‹œ์ž‘ ๋ฒˆํ˜ธ๋ถ€ํ„ฐ ํ˜„์žฌ๊นŒ์ง€ ๋ชจ๋‘ ํŒ€์„ ๋งŒ๋“ค ์ˆ˜ ์—†๋Š” ํ•™์ƒ ๋ฒˆํ˜ธ
  4. n๋ช…์˜ ํ•™์ƒ๋“ค์ด ๋ชจ๋‘ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์œผ๋ฏ€๋กœ, DFS ํƒ์ƒ‰์€ ํ•ญ์ƒ ์œ„ 3๊ฐ€์ง€ ๊ฒฝ์šฐ์˜ ๋์„ ๋ณด๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  1๋ฒˆ๊ณผ 2๋ฒˆ์€ ์‚ฌ์‹ค์ƒ ๊ฐ™์€ ๊ฒฝ์šฐ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  5. ์ค‘์š”ํ•œ๊ฑด ํ•œ๋ฒˆ ํƒ์ƒ‰ํ•œ ๋ฒˆํ˜ธ๋Š” ๋‹ค์‹œ DFS๋ฅผ ํƒ์ƒ‰ํ•˜์ง€ ์•Š๊ฒŒํ•ด์„œ O(n)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.

๐Ÿ”ธ ์ฝ”๋“œ ๐Ÿ”ธ

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

public class Main {

    private static int[] pick, visited;
    private static boolean[] isTeam;

    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;
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());

        for (int t = 0; t < T; t++) {
            int n = Integer.parseInt(br.readLine());
            pick = new int[n];

            st = new StringTokenizer(br.readLine());
            for (int i = 0; i < n; i++) {
                pick[i] = Integer.parseInt(st.nextToken()) - 1;
            }

            int cnt = 0; // ํŒ€์ด ์—†๋Š” ์• ๋“ค ์ˆ˜
            isTeam = new boolean[n]; // ํŒ€ ์†Œ์† ์—ฌ๋ถ€
            visited = new int[n]; // ๋ฐฉ๋ฌธ ์ฒดํฌ
            Arrays.fill(visited, -1);
            for (int i = 0; i < n; i++) {
                if (visited[i] == -1 && !isTeam[i]) { // ๋ฐฉ๋ฌธ ์•ˆํ–ˆ๊ณ , ํŒ€ ์—†์œผ๋ฉด dfs ๋Œ๋ฆผ
                    dfs(i, i);
                }
                if (!isTeam[i]) { // dfs ํ›„์—๋„ ํŒ€ ์—†์œผ๋ฉด ์นด์šดํŠธ
                    cnt++;
                }
            }
            sb.append(cnt).append('\n');
        }
        bw.write(sb.toString());
        bw.flush();
    }

    private static int dfs(int now, int start) {
        // ๋ฐฉ๋ฌธ ํ–ˆ์—ˆ์Œ
        if (visited[now] > -1) {
            if (visited[now] == start) { // ํ˜„์žฌ ํƒ์ƒ‰์— ๋ฐฉ๋ฌธํ•จ : ์„œํด ๋ฐœ์ƒ
                isTeam[now] = true;
                return now;
            } else { // ํŒ€์ด ์žˆ์Œ or ์ด์ „ ๋ฐฉ๋ฌธ
                return -1;
            }
        }

        visited[now] = start;

        // ์žฌ๊ท€
        int result = dfs(pick[now], start);

        if (result > -1 && now != result) { // ํ˜„์žฌ ์„œํด ์•ˆ์ชฝ์ž„
            isTeam[now] = true;
            return result;
        }

        // ์žฌ๊ท€ ๋˜๋Œ์•„ ๊ฐ€๋ฉฐ ์ฒ˜๋ฆฌ ํ•  ๊ฑฐ ์—†์Œ, ์„œํด์ข…๋ฃŒ
        return -1;
    }
}

๐Ÿ”ธ ์ฝ”๋“œ ํ•ด์„ ๐Ÿ”ธ

  • ํ•™์ƒ ๋ณ„ ์„ ํƒ ๋ฒˆํ˜ธ๋ฅผ ์ €์žฅํ•˜๋Š” int ๋ฐฐ์—ด pick, ํŒ€ ์†Œ์†์ด ์žˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” boolean ๋ฐฐ์—ด isTeam, ํƒ์ƒ‰ ์‹œ ์‹œ์ž‘ ๋ฒˆํ˜ธ๋ฅผ ์ €์žฅํ•˜๋Š” int๋ฐฐ์—ด visited๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.
  • n๊ฐœ์˜ ๋ฒˆํ˜ธ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณ„์‚ฐ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
    • ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์•˜๊ณ , ํŒ€์ด ์—†์œผ๋ฉด dfs() ๋ฉ”์„œ๋“œ๋ฅผ ๋Œ๋ฆฐ๋‹ค.
    • ์ดํ›„์—๋„ ํŒ€์ด ์—†์œผ๋ฉด cnt๋ฅผ +1 ํ•œ๋‹ค.
  • dfs ์žฌ๊ท€ ๋ฉ”์„œ๋“œ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณ„์‚ฐ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
    • ๋ฐฉ๋ฌธ ํ™•์ธ
      • ํ˜„์žฌ ํƒ์ƒ‰์— ๋ฐฉ๋ฌธํ–ˆ๋˜ ๋ฒˆํ˜ธ๋ผ๋ฉด, ์„œํด์ด ๋ฐœ์ƒํ•œ ๊ฒƒ์ด๋ฏ€๋กœ, ๋‹ค์‹œ ํ˜„์žฌ ๋ฒˆํ˜ธ๊ฐ€ ๋‚˜์˜ฌ ๋•Œ ๊นŒ์ง€ isTeam[now]์„ true๋กœ ์ –์•„ํ•˜๊ณ  now๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
      • ์ด์ „ ํƒ์ƒ‰ ๋ฐฉ๋ฌธํ–ˆ๋˜ ๋ฒˆํ˜ธ๋ผ๋ฉด, ์„œํด์ด ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์œผ๋ฏ€๋กœ -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    • ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์•˜๋˜ ๋ฒˆํ˜ธ๋ผ๋ฉด ๋ฐฉ๋ฌธ์ฒ˜๋ฆฌํ•œ๋‹ค.
    • ์žฌ๊ท€ ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ
      • dfs(pick[now], start) ๋กœ ๋‹ค์‹œ ์žฌ๊ท€ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
      • ๋งŒ์•ฝ ์žฌ๊ท€ ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜๊ฐ’ result๊ฐ€ 0์ด์ƒ์ด๊ณ  now์™€ ๋‹ค๋ฅด๋‹ค๋ฉด, ์„œํด ์ค‘๊ฐ„์ด๋ฏ€๋กœ istTeam[now]๋ฅผ true๋กœ ๋ฐ”๊ฟ”์ฃผ๊ณ  result๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    • result๊ฐ€ -1์ด๊ฑฐ๋‚˜ result == now๋ผ๋ฉด ์„œํด์ด ์ข…๋ฃŒ๋œ ๊ฒƒ์ด๋ฏ€๋กœ -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๐Ÿ”ธ end ๐Ÿ”ธ

  •  ๋‹จ์ˆœํ•œ DFS ์•Œ๊ณ ๋ฆฌ์ฆ˜๋งŒ ํ•„์š”ํ•œ ๋ฌธ์ œ์ธ๋ฐ, ๋‚œ์ด๋„๊ฐ€ ๊ฝค ๋†’์•˜๋˜ ๊ฒƒ ๊ฐ™๋‹ค.
    • ๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์‹คํ–‰์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ O(n)์œผ๋กœ ํ•ด์•ผ๋ผ์„œ 1ํšŒ ์‹œ๊ฐ„ ์ดˆ๊ณผ ๋‚ฌ๋‹ค.
    • 2๋ฒˆ์งธ ์ œ์ถœ์˜ ํ‹€๋ ธ์Šต๋‹ˆ๋‹ค๋Š” ์ด์ „ ํƒ์ƒ‰์—์„œ ํŒ€์ด ์—†์Œ์„ ์•Œ์•˜๋Š”๋ฐ, ํ˜„์žฌ ํƒ์ƒ‰์—์„œ ๋‹ค์‹œ ๋ฐฉ๋ฌธํ•ด์•ผ ํ•  ๊ฒฝ์šฐ์— ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์„œ ํ‹€๋ ธ๋‹ค. visited๋ฅผ ์ฒ˜์Œ์—” boolean ๋ฐฐ์—ด๋กœ ๋’€๋‹ค๊ฐ€, ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด start๋ฅผ ๊ธฐ๋กํ•˜๊ณ  visited๋ฅผ int๋ฐฐ์—ด๋กœ ๋ฐ”๊ฟ”์„œ ์ฒ˜๋ฆฌํ–ˆ๋‹ค.
  • ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋‹ค์–‘ํ•˜๊ฒŒ ์žˆ๋Š” ๋ฌธ์ œ์ธ ๊ฒƒ ๊ฐ™๋‹ค.
    • ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋‹ค์–‘ํ•˜๊ฒŒ ๋Œ๋ ค๋ณด๋ฉด์„œ ๋””๋ฒ„๊น… ํ•˜๋Š”๊ฒŒ ์ค‘์š”ํ•œ ๊ฒƒ ๊ฐ™์•„์„œ, ์ง์ ‘ ๋งŒ๋“ค๊ธฐ๋„ ํ•˜๊ณ  ์งˆ๋ฌธ ๊ฒŒ์‹œํŒ์— ์žˆ๋Š” ๋ฐ˜๋ก€๋“ค์„ ๋ชจ์œผ๊ธฐ๋„ ํ–ˆ๋‹ค.
    • ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ๋ชจ์Œ์„ ์งˆ๋ฌธ ๊ฒŒ์‹œํŒ์— ๋‚จ๊ฒจ๋†“์•˜๋‹ค.
728x90