사이클 발생 여부를 확인할 수 있다는 점을 활용해 볼 수도 있겠다
BFS 사용
0. 모든 정점의 진입차수를 계산한다.
1. 진입 차수가 0인 노드(시작점)를 큐에 모두 넣는다.
2. 큐에서 진입 차수가 0인 노드를 꺼내어 자신과 인접한 노드의 간선을 제거한다.
-> 인접한 노드의 진입 차수를 1 감소시킨다.
3. 간선 제거 후 진입 차수가 0이 된 노드를 큐에 넣는다.
- 큐가 공백 큐 상태가 될 때까지 2-3 작업을 반복한다.
- 모든 노드가 처리되지 않았다면 사이클 발생
- 모든 노드가 다 처리되었다면 위상 정렬 완성
JAVA
import java.io.*;
import java.util.*;
class Main {
static int N, M;
static List<Integer>[] graph;
static int indegrees[];
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
graph = new ArrayList[N+1];
indegrees = new int[N+1]; // 진입차수 수
for (int n=1; n<=N; n++) {
graph[n] = new ArrayList<Integer>();
}
for (int m=0; m<M; m++) { // 선후관계 입력
st = new StringTokenizer(br.readLine());
int small = Integer.parseInt(st.nextToken());
int tall = Integer.parseInt(st.nextToken());
graph[small].add(tall);
indegrees[tall]++; // 진입차수 수 증가
}
bfs();
System.out.println(sb);
}
static void bfs() {
Deque<Integer> que = new ArrayDeque<>();
// 진입차수가 0인 것들을 인큐
for (int n=1; n<=N; n++) {
if (indegrees[n] == 0) {
que.offer(n);
}
}
while (!que.isEmpty()) {
// 디큐
int now = que.poll();
sb.append(now).append(" ");
for (int num : graph[now]) {
indegrees[num]--;
if (indegrees[num] == 0) {
que.offer(num);
}
}
}
}
}
백준 - 줄 세우기(2252)
위 코드를 제출하면 정답 처리가 된다.
생각보단 그리 구현이 어렵지 않다