
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;
}
}
}
}
}