※ 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 34679번 문제인 홍수이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/34679
주어진 문제의 상황을 각 하수구를 노드로, 물이 흐를 수 있는 두 하수구의 관계를 방향이 있는 에지로 하는 그래프로 모델링해보자. 이와 같은 모델에서 주어진 문제는 그래프의 모든 노드에서 입력으로 주어진 "물이 고이지 않는 하수구" 노드 중 적어도 하나에 도달할 수 있는지를 판단하는 것으로 해결할 수 있게 된다.
그러나 각 노드마다 "물이 고이지 않는 하수구"에 도달할 수 있는지 한 번씩 탐색해보는 것은 비효율적이다. 특히, 잘 구성된 일자 그래프가 주어지면 시간초과가 발생하게 된다. 다른 방법을 생각해보자.
각 노드에서 어떤 "물이 고이지 않는 하수구"에 도달할 수 있다는 것은, 주어진 그래프와 간선의 방향을 뒤집은 그래프(Transpose Graph라고 부른다)에서 각 노드마다 도달할 수 있는 "물이 고이지 않는 하수구"가 적어도 하나씩 있다는 것과 같다는 점을 관찰하자. 따라서, 주어진 "물이 고이지 않는 하수구" 노드로부터 도달할 수 있는 노드의 집합이 전체 노드의 집합과 같은지를 판단하는 것으로 문제를 해결할 수 있다.
이와 같은 문제 상황은 multisource BFS 등으로 어렵지 않게 해결할 수 있다. 글쓴이는 그냥 스택을 이용하여 그래프 탐색을 진행하였다.
높이가 같은 두 하수구 사이에서는 배수로가 있어도 어떠한 방향 에지도 생성되지 않는다는 점에 주의하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
int N, M, K;
int H[200001];
bool visited[200001];
vector<int> G[200001];
vector<int> stk;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M;
for (int i = 1; i <= N; i++) cin >> H[i];
while (M--) {
int x, y; cin >> x >> y;
if (H[x] > H[y]) G[y].emplace_back(x);
else if (H[x] < H[y]) G[x].emplace_back(y);
}
cin >> K;
while (K--) {
int x; cin >> x;
visited[x] = 1;
stk.emplace_back(x);
}
while (!stk.empty()) {
int x = stk.back(); stk.pop_back();
for (auto &nxt:G[x]) {
if (visited[nxt]) continue;
visited[nxt] = 1;
stk.emplace_back(nxt);
}
}
for (int i = 1; i <= N; i++) {
if (!visited[i]) cout << "flood", exit(0);
}
cout << "no flood";
}'BOJ' 카테고리의 다른 글
| [BOJ 34803 // C++] 문자열 로또 (0) | 2025.11.28 |
|---|---|
| [BOJ 26570 // C++] Semiperfect (0) | 2025.11.27 |
| [BOJ 29338 // C++] Склад Оби-Вана Кеноби (0) | 2025.04.03 |
| [BOJ 29343 // C++] Шифровка (0) | 2025.04.02 |
| [BOJ 33689 // C++] CPDU (0) | 2025.04.01 |