문제
- 문제 링크
BOJ 26359 - A Prickly Problem – Black Edition
$V$개의 정점으로 이루어진 $Cactus$ $Graph$가 주어진다.
스패닝 트리가 되도록 $V-1$개의 간선만을 남겼을 때, 서로 다른 모양의 트리가 존재할 수 있다.
이 스패닝 트리의 가짓수에 대해 $1,007$로 나눈 나머지를 출력하자.
TL : $1$ sec, ML : $1024$ MB
$1 ≤ V ≤ 50,000$ $1 ≤ E ≤ (3*V)/2$ 주어지는 그래프는 $Cactus$ $Graph$임이 보장된다. 입력은 여러 개의 테스트 케이스로 이루어져 있다.
알고리즘 분류
- 그래프 이론 (graphs)
- 이중 연결 요소 (biconnected_component)
- 선인장 (cactus)
풀이
어떤 스패닝 트리를 만들기 위해 간선 $E$를 제거할 때, $E$가 $articulation$ $edge$라면 제거할 수 없다.
즉, 우리가 제거한다고 가정해야 할 $E$는 반드시 단순 사이클 위에 있는 간선이어야 한다.
주어진 그래프에서, $biconnected$ $component$들을 모두 찾아내어보자.
$1$개의 간선을 포함한 컴포넌트도 $biconnected$ $component$의 정의에 부합한다.
그러나, 지금은 단순 사이클만이 필요하기 때문에 이들은 제외해야 함을 유의하자.
찾은 컴포넌트들을 $bcc_1, bcc_2, ... , bcc_k$라 할 때, 어떻게 스패닝 트리를 만들 수 있을까?
이는 존재하는 모든 사이클들을 끊어주면 되므로, 각 $bcc$에서 간선을 하나씩 지워주면 된다.
문제에서는 가짓수를 묻고 있으므로, 답은 $(Size(bcc_1) * Size(bcc_2) * ... * Size(bcc_k))$ $mod$ $1007$가 된다.
따라서 $bcc$들을 저장할 때 실제 구성 원소들을 갖고 있을 필요는 없고, 규모만 저장하면 된다.
전체 코드
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 | #include<bits/stdc++.h> using namespace std; vector <int> Gr[50001]; vector <int> bcc; stack <int> st; int in[50001]; int n, m, cur; void Input() { scanf("%d %d", &n, &m); for (int u, v; m--;) { scanf("%d %d", &u, &v); Gr[u].push_back(v); Gr[v].push_back(u); } } int DFS(int now, int prev) { int _min(in[now] = ++cur); for (int& nxt : Gr[now]) if (nxt ^ prev) { if (in[now] > in[nxt]) st.push(nxt); if (!in[nxt]) { int temp(DFS(nxt, now)); if (temp >= in[now]) { int sz{}; while (1) { int top(st.top()); st.pop(); sz++; if (top == nxt) break; } if (sz > 1) bcc.push_back(sz); } _min = min(_min, temp); } _min = min(_min, in[nxt]); } return _min; } void End(int tc, int ans = 1) { for (int& cnt : bcc) ans = (ans * cnt) % 1007; printf("Case #%d: %d\n\n", tc, ans); bcc = {}, st = {}, cur = 0; for (int i{}; i <= n; i++) { Gr[i].clear(); in[i] = 0; } } int main() { int t; scanf("%d", &t); for (int tc(1); tc <= t; tc++) { Input(); DFS(1, 1); End(tc); } } | cs |
comment
끝
'Problem Solving > Baekjoon Online Judge (Platinum)' 카테고리의 다른 글
백준 23314 - Minimum Spanning Cactus (C++) (1) | 2023.10.09 |
---|---|
백준 21025 - Healthy Lifestyle (C++) (1) | 2023.10.04 |
백준 11817 - Robots and Oil Transportation System (C++) (1) | 2023.09.30 |
백준 9548 - 무제 (C++) (0) | 2023.09.28 |
백준 18425 - Putovanje (C++) (2) | 2023.09.28 |