문제 출처

1. 문제설명


  • 보조 PD들이 만든 순서들이 입력으로 주어질 때, 전체 가수 순서를 정하라
    • 모두가 만족하는 순서 출력
    • 만약 불가능 하다면 0
  • 문제 분류
    • Graph, Topological Sorting


2. 알고리즘 설계


  • 위상정렬(Topological Sorting) 기본 문제이다.
  • 이전 문제와 달리 위상 정렬의 조건이 성립하지 않는지까지 체크한다.
  • 위상 정렬은 한번도 가르켜지지않은 노드들을 순차적으로 큐에 집어넣고, 하나씩 꺼내면서 현재 노드가 가르키는 노드의 가르킴 횟수를 줄인다.
    • 그리고 만약 가르킴 횟수가 0이라면 큐에 넣는다.
  • 여기서 큐가 비어서 루프가 끝났다. 그렇다면 어떤 결과값이 보장되어야 할까?
    • 위상 정렬 결과를 노드번호로 벡터에 저장했다면, 벡터의 원소의 개수와 원래 원소의 개수가 같아야 한다.
    • 그렇다! 루프 종료 후에 N == res.size()를 체크해주면 이번 문제와 이전 문제는 차이가 거의 없다.


3. 전체 코드


#include <bits/stdc++.h>
using namespace std;

const int SZ = 1'002;
int n, m, cnt, a, b, deg[SZ];
vector<int> adj[SZ], res;
queue<int> q;

int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> m;
    while(m--) {
        cin >> cnt;
        cin >> a;
        for(int i=1; i<cnt; i++) {
            cin >> b;
            adj[a].push_back(b);
            deg[b]++;
            a = b;
        }
    }

    for(int i=1; i<=n; i++)
        if(deg[i] == 0) q.push(i);
    
    while(!q.empty()) {
        int cur = q.front();
        q.pop();

        res.push_back(cur);

        for(int nxt : adj[cur]) {
            deg[nxt]--;
            if(deg[nxt] == 0) q.push(nxt);
        }
    }

    if(res.size() != n) cout << 0;
    else 
        for(int a : res) cout << a << '\n';

    return 0;
}