Baekjoon 2252 - 줄 세우기 (클릭 시 이동)
문제
N명의 학생들을 키 순서대로 줄을 세우려고 한다. 각 학생의 키를 직접 재서 정렬하면 간단하겠지만, 마땅한 방법이 없어서 두 학생의 키를 비교하는 방법을 사용하기로 하였다. 그나마도 모든 학생들을 다 비교해 본 것이 아니고, 일부 학생들의 키만을 비교해 보았다.
일부 학생들의 키를 비교한 결과가 주어졌을 때, 줄을 세우는 프로그램을 작성하시오.
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
---|---|---|---|---|---|
2 초 | 128 MB | 27156 | 15255 | 9965 | 54.792% |
입력
첫째 줄에 N(1 ≤ N ≤ 32,000), M(1 ≤ M ≤ 100,000)이 주어진다. M은 키를 비교한 회수이다. 다음 M개의 줄에는 키를 비교한 두 학생의 번호 A, B가 주어진다. 이는 학생 A가 학생 B의 앞에 서야 한다는 의미이다.
학생들의 번호는 1번부터 N번이다.
출력
첫째 줄에 학생들을 키 순서대로 줄을 세운 결과를 출력한다. 답이 여러 가지인 경우에는 아무거나 출력한다.
풀이 ( 위상 정렬 )
변수 설명 : indegree - 자신을 가리키는 다른 노드의 수
- 단방향 그래프를 구현한다
- 입력이 start end 순으로 주어진다면 end의 indegree를 1만큼 증가시킨다.
- BFS를 수행하는데, indegree 값이 0인 정점을 모두 queue에 넣는다.
- 그래프를 탐색하며 만나는 정정의 indegree를 1만큼 감소시킨다. 이 때 값이 0이되면 queue에 넣는다.
- 더이상 자신을 가리키는게 없는 노드들만 queue에 들어가므로 queue에서 poll 할 때마다 출력해준다.
최종 소스코드
import java.io.*;
import java.util.*;
public class BJ_G3_2252_줄_세우기 {
static int N, M;
static Node[] adjList;
static int[] indegree;
static StringBuilder sb = new StringBuilder();
static class Node {
int vertex;
Node link;
public Node(int vertex, Node link) {
this.vertex = vertex;
this.link = link;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
adjList = new Node[N + 1];
indegree = new int[N + 1];
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken());
int end = Integer.parseInt(st.nextToken());
adjList[start] = new Node(end, adjList[start]);
indegree[end]++; // end를 가리키는 노드의 수를 1개 증가시킨다.
}
bfs();
System.out.println(sb.toString());
}
static void bfs() {
Queue<Integer> queue = new LinkedList<>();
for (int i = 1; i <= N; i++) {
if (indegree[i] == 0) // indegree가 0인 정점을 queue에 넣는다.
queue.offer(i);
}
while (!queue.isEmpty()) {
int cur = queue.poll(); // 더이상 자신을 가리키는 노드가 없는 노드만 queue에 존재한다.
sb.append(cur).append(" "); // 그러므로 바로 출력
for(Node temp = adjList[cur]; temp != null ; temp = temp.link){ // 연결된 노드를 탐색한다.
if(--indegree[temp.vertex] == 0) // 1만큼 감소시키고 0이되었다면 queue에 넣는다.
queue.offer(temp.vertex);
}
}
}
}
'Algorithm > BaekJoon' 카테고리의 다른 글
[백준] 11967번 - 불켜기(java) (0) | 2022.02.04 |
---|---|
[백준] 5014번 - 스타트링크 (java) (0) | 2022.02.01 |
[백준] 16472 - 고냥이 (java) (0) | 2022.01.29 |
[백준] 16945번 - 움직이는 미로 탈출 (java) (0) | 2022.01.23 |
[백준] 17836번 - 공주님을 구하라! (java) (0) | 2022.01.16 |