[백준] 효율적인 해킹(1325)

Wonho Kim·2025년 3월 19일

Baekjoon

목록 보기
39/42

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

A가 B를 신뢰하는 경우 B를 해킹하면, A도 해킹할 수 있다는 것이 핵심이다.

예제 입력을 기준으로 분석해보면 다음과 같다.

N = 5, M = 4

3은 1을 신뢰 -> 1을 해킹하면 3을 해킹 가능
3은 2를 신뢰 -> 2를 해킹하면 3을 해킹 가능
4는 3을 신뢰 -> 3을 해킹하면 4를 해킹 가능
5는 3을 신뢰 -> 3을 해킹하면 5를 해킹 가능

1을 해킹하면 -> 3 해킹 -> 4 해킹 가능
1을 해킹하면 -> 3 해킹 -> 5 해킹 가능
2를 해킹하면 -> 3 해킹 -> 4 해킹 가능
2를 해킹하면 -> 3 해킹 -> 5 해킹 가능

그래서 한 번에 가장 많은 컴퓨터를 해킹할 수 있는 1, 2번이 정답으로 출력된다.

따라서 주어진 모든 노드에 대해 BFS 탐색을 수행하되, 다음 노드로 이동할 때 카운트를 올려주어 값을 세주는 배열(trust)이 필요하다.

int[] trust = new int[N + 1];

...

static void BFS(int v) {
	...
    
    while (!queue.isEmpty()) {
            int nowNode = queue.poll();

            for (int i : A[nowNode]) {
                if (!visited[i]) {
                    queue.add(i);
                    trust[i]++;
                    visited[i] = true;
                }
            }
        }
	...

trust 배열의 수행과정을 생각해보면 다음과 같다.

trust = [0, 0, 0, 0, 0, 0]

1, 2번 노드 탐색 후
trust = [0, 0, 0, 0, 0, 0]

3번 노드 탐색 후
trust = [0, 1, 1, 0, 0, 0]

4번 노드 탐색 후
trust = [0, 2, 2, 1, 0, 0]

5번 노드 탐색 후
trust = [0, 3, 3, 2, 0, 0]

이를 통해 trust 배열의 최댓값은 3인 점을 파악할 수 있고, 최댓값에 부합하는 모든 인덱스를 출력하면 정답이 된다.

따라서 전체 소스코드는 다음과 같다.

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

public class P_1325 {
    static boolean[] visited;
    static ArrayList<Integer>[] A;
    static int N, M;
    static int[] trust;

    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());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        A = new ArrayList[N + 1];
        for (int i = 1; i <= N; i++) {
            A[i] = new ArrayList<>();
        }

        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());

            int start = Integer.parseInt(st.nextToken());
            int end = Integer.parseInt(st.nextToken());

            A[start].add(end);
        }

        trust = new int[N + 1];
        for (int i = 1; i <= N; i++) {
            visited = new boolean[N + 1];
            BFS(i);
        }

        int Max = 0;
        for (int i = 1; i <= N; i++) {
            Max = Math.max(Max, trust[i]);
        }

        for (int i = 1; i <= N; i++) {
            if (Max == trust[i]) {
                bw.write(i + " ");
            }
        }

        bw.flush();
        bw.close();
    }

    static void BFS(int v) {
        Queue<Integer> queue = new LinkedList<>();

        queue.add(v);
        visited[v] = true;

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

            for (int i : A[nowNode]) {
                if (!visited[i]) {
                    queue.add(i);
                    trust[i]++;
                    visited[i] = true;
                }
            }
        }
    }
}
profile
새싹 백엔드 개발자

0개의 댓글