https://www.acmicpc.net/problem/2252
N명의 학생들을 키 순서대로 줄을 세우려고 한다.A, B가 주어지면, 이는 학생 A가 B의 앞에 서야 한다는 의미이다.전형적인 위상 정렬 문제입니다.
인접리스트를 사용하여 a, b가 주어지면 a인덱스에 b를 추가하고 b 앞에 한 사람이 추가됨을 나타내면 쉽게 풀 수 있는 알고리즘입니다.
private static void init() {
ind = new int[n+1];
graph = new ArrayList<>();
for (int i = 0; i <= n; i++) graph.add(new ArrayList<>());
}
ind: 본인 앞에 몇 명이 존재하는지 알 수 있는 배열graph: 본인 뒤에 존재하는 사람들의 목록을 저장할 배열 for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
graph.get(a).add(b);
++ind[b];
}
private static void topology() {
res = new ArrayList<>(); // 학생들의 키 순서를 나타낼 배열
Queue<Integer> queue = new ArrayDeque<>();
// 이미 앞에 아무도 없는 사람들이면 queue에 추가
for (int i = 1; i <= n; i++) {
if (ind[i] == 0) {
queue.add(i);
}
}
while (!queue.isEmpty()) {
int cur = queue.poll();
res.add(cur); // 이미 앞에 아무도 없으므로 정답 배열에 추가
// 본인보다 작은 사람들 탐색
for (int v : graph.get(cur)) {
--ind[v];
if (ind[v] == 0) {
queue.add(v);
}
}
}
}
ind[v]를 감소시키는 이유는 이미 본인보다 앞에 있는 사람이 정답 배열에 추가가됨으로써, 이 사람을 고려할 필요가 없어졌기 때문입니다.ind는 나보다 앞에 있는 사람이 몇 명인가?를 나타내는 배열입니다.import java.util.*;
import java.io.*;
public class Main_2252 {
static int n, m;
static int[] ind;
static List<Integer> res;
static List<ArrayList<Integer>> graph;
private static void init() {
ind = new int[n+1];
graph = new ArrayList<>();
for (int i = 0; i <= n; i++) graph.add(new ArrayList<>());
}
private static void topology() {
res = new ArrayList<>();
Queue<Integer> queue = new ArrayDeque<>();
for (int i = 1; i <= n; i++) {
if (ind[i] == 0) {
queue.add(i);
}
}
while (!queue.isEmpty()) {
int cur = queue.poll();
res.add(cur);
for (int v : graph.get(cur)) {
--ind[v];
if (ind[v] == 0) {
queue.add(v);
}
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
init();
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
graph.get(a).add(b);
++ind[b];
}
topology();
for (int v : res) System.out.print(v + " ");
}
}