ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [6543] 그래프의 싱크
    BOJ 2021. 12. 17. 12:19

    https://www.acmicpc.net/problem/6543

     

    6543번: 그래프의 싱크

    각 테스트 케이스마다 한 줄에 걸쳐 bottom(G)의 모든 노드를 출력한다. 노드는 공백으로 구분해야 하며, 오름차순이어야 한다. 만약, bottom(G)가 공집합이면 빈 줄을 출력한다.

    www.acmicpc.net

    <문제>

    SCC만들어서, outdegree가 0인 정점을 출력하면 된다.

    코드에는 ind[]로 되어있는데...변수명을 수정하지 않아서 그렇다. 

    SCC로 DAG만들어서 위상정렬하는 테크닉이 적용되다 만(?) 문제들이 몇개 있는거같다.

    위상정렬을 절반만 구현하는 듯한 느낌인데, 이 문제는 위상정렬에서 큐에 넣는 부분까지만 구현해주면 충분하다.

     

    <소스코드>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    #include <bits/stdc++.h>
    using namespace std;
    int n, m, cnt, d[100001], SN, sn[100001];
    bool checked[100001];
    vector<int> adj[100001];
    vector<vector<int>> scc;
    stack<int> s;
    int dfs(int cur) {
        d[cur] = ++cnt;
        s.push(cur);
        int res = d[cur];
        for (int next : adj[cur]) {
            if (d[next] == 0)
                res = min(dfs(next), res);
            else if (!checked[next])
                res = min(res, d[next]);
        }
        if (res == d[cur]) {
            vector<int> temp;
            while (1) {
                int x = s.top();
                s.pop();
                temp.push_back(x);
                checked[x] = true;
                sn[x] = SN;
                if (x == cur) break;
            }
            sort(temp.begin(), temp.end());
            scc.push_back(temp);
            SN++;
        }
        return res;
    }
    int main(void) {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        while (1) {
            cin >> n;
            if (n == 0break;
            m = cnt = SN = 0;
            memset(d, 0sizeof(d));
            memset(sn, 0sizeof(sn));
            memset(checked, 0sizeof(checked));
            int i;
            for (i = 0; i <= 100000; i++) adj[i].clear();
            scc.clear();
     
            cin >> m;
            for (i = 0; i < m; i++) {
                int x, y;
                cin >> x >> y;
                adj[x - 1].push_back(y - 1);
            }
            for (i = 0; i < n; i++)
                if (d[i] == 0) dfs(i);
            sort(scc.begin(), scc.end());
            int ind[100001= {0};
            for (i = 0; i < n; i++)
                for (int j : adj[i])
                    if (sn[i] != sn[j]) ind[sn[i]]++;
            for (i = 0; i < n; i++)
                if (ind[sn[i]] == 0cout << i + 1 << " ";
            cout << '\n';
        }
        return 0;
    }
     
    cs

     

    'BOJ' 카테고리의 다른 글

    [2749] 피보나치 수 3  (0) 2021.12.19
    [10826] 피보나치 수 4  (0) 2021.12.18
    [1292] 쉽게 푸는 문제  (0) 2021.12.15
    [2816] 디지털 티비  (0) 2021.12.14
    [21313] 문어  (0) 2021.12.10

    댓글