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

 

4196번: 도미노

문제 도미노는 재밌다. 도미노 블록을 일렬로 길게 늘어세운 뒤 블록 하나를 넘어뜨리면 그 블록이 넘어지며 다음 블록을 넘어뜨리는 일이 반복되어 일렬로 늘어선 블록들을 연쇄적으로 모두

www.acmicpc.net

SCC 그룹후 이것을 처리하는 방법에서 막히였다. 만일 이런 SCC 그룹이 존재할때 답은 2라는것은 직관적으로 알것이다.

하지만 어떻게 2라는걸 나타낼 것인가??? 답은 밑에

 

 

 

 

 

Group에 대한 위상정렬 indegree배열을 만들고 indegree가 0인 개수를 새주면 된다.

즉 group1, 3이 0이니깐 답은 2개. 놀랍다!!

 

 

 

 

 

 

 

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std;
 
 
vector<int> edge[100001];
stack<int>s;
bool finish[100001];
int dfsn[100001];
int group[100001];
int indegree[100001];
int g_num;
int dcnt;
int v, e;
 
int SCC(int cur)
{
    dfsn[cur] = ++dcnt;
    s.push(cur);
    int result = dfsn[cur];
    for (int i = 0; i < edge[cur].size(); i++)
    {
        int next = edge[cur][i];
        if (dfsn[next] == 0)
            result = min(result, SCC(next));
        else if (finish[next] == false)
            result = min(result, dfsn[next]);
    }
 
    if (result == dfsn[cur])
    {
        g_num++;
        while (!s.empty())
        {
            int t = s.top();
            s.pop();
            group[t] = g_num;
            finish[t] = true;
            if (t == cur)
                break;
        }
    }
 
    return result;
}
 
void init()
{
    
    for (int i = 1; i <= v; i++)
    {
        edge[i].clear();
        dfsn[i] = 0;
        finish[i] = false;
        group[i] = 0;
        indegree[i] = 0;
    }
    dcnt = 0;
    g_num = 0;
}
 
int main()
{
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    int tc;
    cin >> tc;
 
    for (int z = 0; z < tc; z++)
    {
        
        int a,b;
        cin >> v >> e;
        init();
 
 
        for (int i = 0; i < e; i++)
        {
            cin >> a >> b;
            edge[a].push_back(b);
        }
 
        for (int i = 1; i <= v; i++)
        {
            if (dfsn[i] == 0)
                SCC(i);
        }
 
        for (int i = 1; i <= v; i++)
        {
            for (int j = 0; j < edge[i].size(); j++)
            {
                a = group[i]; b = group[edge[i][j]];
                if (a == b)
                    continue;
                indegree[b]++;
            }
        }
        int ans = 0;
        for (int i = 1; i <= g_num; i++)
        {
            if (indegree[i] == 0)
                ans++;
        }
        cout << ans << '\n';
        
    }
}
 
cs

'뚝배기 터진 문제_boj' 카테고리의 다른 글

boj 19235 모노미노도미노  (0) 2020.10.17
boj3176 도로 네트워크  (0) 2020.08.20
boj17387 선분 교차 2  (0) 2020.07.17
boj2618 경찰차  (0) 2020.07.15
boj1086 박성원  (0) 2020.07.03

+ Recent posts