2 λΆ„ μ†Œμš”

πŸ“ [D4_5643] ν‚€ μˆœμ„œ

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Solution {
	static int N;
	static int[][] adjMatrix;

	public static void main(String[] args) throws IOException {
		StringTokenizer st;
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();

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

		for (int tc = 1; tc <= T; tc++) {
			sb.append("#").append(tc).append(" ");

			// ν•™μƒμˆ˜
			N = Integer.parseInt(br.readLine());

			// 비ꡐ 횟수
			int M = Integer.parseInt(br.readLine());

			// ν•™μƒλ²ˆν˜Έ 1λΆ€ν„° μ‹œμž‘ν•˜λ„λ‘..
			// 인접행렬 : 0이면 킀관계 λͺ¨λ¦„ 1이면 μžμ‹ λ³΄λ‹€ ν‚€κ°€ 큰 ν•™μƒκ³Όμ˜ 관계λ₯Ό ν‘œν˜„
			adjMatrix = new int[N + 1][N + 1];

			// 탐색전인 κ²ƒμœΌλ‘œ μ΄ˆκΈ°ν™” ( λ‚˜λ³΄λ‹€ ν¬κ±°λ‚˜ μž‘μ€μ• λ“€μ΄ μ—†λŠ” 경우 0이 λ‚˜μ˜¬ 수 있기 λ•Œλ¬Έμ— κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ -1둜 μ΄ˆκΈ°ν™” ν•΄μ€€λ‹€.)
			for (int i = 1; i <= N; i++) {
				adjMatrix[i][0] = -1;
			}

			// λ‹€λŒκ³ λ‚˜λ©΄ 배열이 μ™„μ„±
			for (int i = 0; i < M; i++) {
				st = new StringTokenizer(br.readLine(), " ");
				int a = Integer.parseInt(st.nextToken());
				int b = Integer.parseInt(st.nextToken());
				// a보닀 bκ°€ 크닀
				adjMatrix[a][b] = 1;
			}

			
			for (int i = 1; i <= N; i++) {
				// 탐색전인 ν•™μƒλ“€λ§Œ 탐색
				if (adjMatrix[i][0] == -1) {
					gtDfs(i);
				}
			}
			
			// λ‚˜λ³΄λ‹€ μž‘μ€ ν•™μƒμˆ˜ μΉ΄μš΄νŒ…
			for (int i = 1; i <= N; i++) {
				for (int j = 1; j <= N; j++) {
					adjMatrix[0][j] += adjMatrix[i][j];
				}
			}
			
			// μžμ‹ μ˜ ν‚€λ₯Ό μ•Œ 수 μžˆλŠ” 학생 수
			int answer = 0;
			
			// 총 ν•© κ΅¬ν•˜κΈ°
			for (int i = 1; i <= N; i++) {
				if(adjMatrix[i][0] + adjMatrix[0][i] == N-1) {
					answer++;
				}
			}

			sb.append(answer).append("\n");
		}
		System.out.println(sb);
	}

	// μžμ‹ λ³΄λ‹€ 큰 학생 탐색
	static void gtDfs(int cur) {
		
		for (int i = 1; i <= N; i++) {
            // 원리
            // i > j && j > z -> i > z

			// λ‚˜λ³΄λ‹€ 큰 학생이면
			if (adjMatrix[cur][i] != 0) {

				// νƒμƒ‰ν•œ 적 μ—†λ‹€
				if (adjMatrix[i][0] == -1) {
					gtDfs(i);
				}

				// λ‚˜λ³΄λ‹€ 큰 학생이 μ•Œκ³ μžˆλŠ” λ‹€λ₯Έ ν•™μƒκ³Όμ˜ ν‚€ 관계λ₯Ό λ‚˜μ™€μ˜ 직접 κ΄€κ³„λ‘œ 맀핑
				// i 보닀 큰 학생이 μžˆλ‹€λ©΄ ( 0 μΈκ²½μš°λŠ” 큰학생이 μ—†λŠ” κ²½μš°λ‹€ )
				if (adjMatrix[i][0] > 0) {
					for (int j = 1; j <= N; j++) {
						// cur < i < j==> cur < j
						if(adjMatrix[i][j] == 1) {
							adjMatrix[cur][j] = 1;
						}
					}
				}

			}
		}
		
		// 기둝 - λ‹€ λ°°μ—΄μ˜ 첫번째 ( 0 )에 더해둔닀
		
		int cnt = 0;
		for (int i = 1; i <= N; i++) {
			cnt += adjMatrix[cur][i];
		}
		adjMatrix[cur][0] = cnt;
	}
}

πŸ€” λ‚˜μ˜ 생각

문제 풀이
이 λ¬Έμ œλŠ” κ·Έλž˜ν”„μ˜ λŒ€ν‘œμ μΈ 문제라 μ—¬λŸ¬κ°€μ§€ ν’€μ΄λ²•μœΌλ‘œ 정리해 λ³΄μ•˜λ‹€.