문제
https://www.acmicpc.net/problem/2623
2623번: 음악프로그램
첫째 줄에는 가수의 수 N과 보조 PD의 수 M이 주어진다. 가수는 번호 1, 2,…,N 으로 표시한다. 둘째 줄부터 각 보조 PD가 정한 순서들이 한 줄에 하나씩 나온다. 각 줄의 맨 앞에는 보조 PD가 담당한
www.acmicpc.net
구현 방법
출연 순서가 정해져 앞 가수가 먼저 출연해야 다음 가수가 출연할 수 있으므로 위상 정렬 알고리즘을 사용했습니다.
입력이 여러 가지로 나뉘어 들어오지만 결국 하나의 그래프임을 알 수 있습니다.
각 보조 PD가 담당하는 순서 관계를 전부 저장한 뒤 위상 정렬을 돌리면 끝~.~
위상 정렬을 단계별로 나열하면
1. 가수들의 진입 차수를 확인하여 0인 가수만 큐에 삽입 (가수 번호 저장)
2. 큐에 삽입한 가수들을 하나씩 빼내어 이동할 수 있는 정점 확인
3. 이동할 수 있는 정점의 진입 차수가 0이면 큐에 삽입
4. 2-3 반복하다 순서를 확정지은 가수의 수가 전체 가수의 수와 같다면 true 출력
5. 만약 큐가 빈 값이 될 때까지 모든 가수의 순서를 정하지 못했다면 false 출력
6-1. 출연 순서가 모두 정해지면 저장해놓았던 가수 번호 출력
6-2. 출연 순서가 모두 정해지지 않았다면 0 출력
구현 코드
package BOJ.Gold;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
public class B2623_음악프로그램 {
static int N, M, inDegree[], cnt;
static List<List<Integer>> list = new ArrayList<>();
static Queue<Integer> queue = new LinkedList<>();
static StringBuilder sb = new StringBuilder();
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());
inDegree = new int[N+1];
for (int i=0;i<=N;i++) {
list.add(new ArrayList<>());
}
for (int i=0;i<M;i++) {
st = new StringTokenizer(br.readLine());
int size = Integer.parseInt(st.nextToken()); // 보조 PD가 담당하는 가수 수
int from = Integer.parseInt(st.nextToken());
for (int j=1;j<size;j++) {
int to = Integer.parseInt(st.nextToken());
list.get(from).add(to); // 간선 저장
inDegree[to]++; // 진입 차수 저장
from = to; // 현재 뒷 순서가 다음의 앞 순서
}
}
if (topology()) System.out.println(sb);
else System.out.println(0);
}
static boolean topology() {
for (int i=1;i<=N;i++) {
if (inDegree[i] == 0) { // 진입 차수가 0이면 진입 가능
queue.offer(i);
sb.append(i+"\n"); // 순서 저장
cnt++;
}
}
while(!queue.isEmpty()) {
int now = queue.poll();
for (int next : list.get(now)) { // 이동할 수 있는 정점 중
if (--inDegree[next] == 0) { // 진입 차수가 0이면 진입 가능
queue.offer(next);
sb.append(next+"\n");
// 모든 가수들의 순서를 정하면 true 리턴
if (++cnt == N) return true;
}
}
}
// 순서를 정하는 것이 불가능하면 false
return false;
}
}
'백준' 카테고리의 다른 글
백준 16940번 : BFS 스페셜 저지 (Java) (0) | 2022.02.23 |
---|---|
백준 7662번 : 이중 우선순위 큐 (Java) (0) | 2022.02.22 |
백준 1938번 : 통나무 옮기기 (Java) (0) | 2022.02.21 |
백준 1005번 : ACM Craft (Java) (0) | 2022.02.19 |
백준 17244번 : 아맞다우산 (Java) (0) | 2022.02.18 |