반응형

문제 출처 :


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



알고리즘 분석 :


문제 해결에 필요한 사항

1. SCC :: http://www.crocus.co.kr/950


SCC를 알면 풀 수 있는 기본이 되는 문제이다.


여기서 SCC이외에 요구사항은 정렬을 해서 출력하고 출력의 끝에 -1을 붙여 출력해달라는 것 이외에는 다른 요구사항은 없다.


위의 링크에서 SCC를 공부하고 문제를 풀어보면 될 것 같다.











소스 코드 : 


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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <cstdio>
#include <vector>
#include <stack>
#include <algorithm>
 
using namespace std;
 
const int MAX = 10010;
 
// SCCtotal : SCC 개수, sn[i]: i가 속한 SCC의 번호
int V, E, cnt, dfsn[MAX], SCCtotal, sn[MAX];
vector<int> adj[MAX];
bool finished[MAX]; // SCC가 확정된 정점 판별
stack<int> s;
vector<vector<int>> SCC;
 
// SCC에 사용될 dfs
int dfs(int curr)
{
    dfsn[curr] = ++cnt; // dfsn 결정
    s.push(curr); // 스택에 자신을 push
 
    // 자신의 dfsn, 자식들의 결과나 dfsn 중 가장 작은 번호를 result에 저장
    int result = dfsn[curr];
    for (int next : adj[curr])
    {
        // 아직 방문하지 않은 이웃
        if (dfsn[next] == 0)
            result = min(result, dfs(next));
 
        // 방문은 했으나 아직 SCC로 추출되지는 않은 이웃
        else if (!finished[next])
            result = min(result, dfsn[next]);
    }
 
    // 자신, 자신의 자손들이 도달 가능한 제일 높은 정점이 자신일 경우 SCC 추출
    if (result == dfsn[curr])
    {
        vector<int> curSCC;
        // 스택에서 자신이 나올 때까지 pop
        while (1)
        {
            int t = s.top();
            s.pop();
            curSCC.push_back(t);
            finished[t] = true;
            sn[t] = SCCtotal;
 
            if (t == curr)
                break;
        }
 
        // 출력을 위해 원소 정렬
        sort(curSCC.begin(), curSCC.end());
 
        // SCC에 현재 이루어진 SCC 정보 push_back
        SCC.push_back(curSCC);
        SCCtotal++// SCC 개수 
    }
 
    return result;
}
 
int main() {
    // 그래프 정보 입력
    scanf("%d %d"&V, &E);
    for (int i = 0; i< E; i++) {
        int from, to;
        scanf("%d %d"&from, &to);
        adj[from].push_back(to);
    }
 
    // DFS를 하며 SCC 추출
    for (int i = 1; i <= V; i++)
        if (dfsn[i] == 0)
            dfs(i);
 
    // 출력을 위해 SCC들을 정렬
    sort(SCC.begin(), SCC.end());
 
    // SCC 개수
    printf("%d\n", SCCtotal);
 
    // 각 SCC 출력
    for (auto& currSCC : SCC)
    {
        for (int curr : currSCC)
            printf("%d ", curr);
 
        printf("-1\n");
    }
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus

반응형

'Applied > 알고리즘 문제풀이' 카테고리의 다른 글

[4196번] 도미노  (0) 2017.07.22
[6543번] The Bottom of a Graph  (0) 2017.07.22
[2042번] 구간 합 구하기  (0) 2017.07.18
[11050번] 이항계수 1  (0) 2017.07.18
[2622번] 삼각형만들기  (0) 2017.07.18