※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 25187번 문제인 고인물이 싫어요이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/25187
25187번: 고인물이 싫어요
첫째 줄에 물탱크의 수 $N(1 \leq N \leq 100\,000)$과 파이프의 수 $M(0 \leq M \leq 200\,000)$, 그리고 물탱크에 방문할 횟수 $Q(1 \leq Q \leq 100\,000)$가 주어진다. 둘째 줄에 $1$번부터 $N$번 물탱크까지 순서대
www.acmicpc.net
각 connected component를 한번씩 순회하면서 고인물 물탱크와 청정수 물탱크의 개수를 먼저 세고, 그 개수에 따라 그 connected component의 각 노드에서 청정수를 구할 수 있을지의 여부, 즉 답을 한번에 전처리해두자.
모든 노드(물탱크)와 에지는 각각 한번/두번씩 방문하므로 시간복잡도는 O(N+M)이다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
bool water[100001];
vector<int> G[100001];
bool visited[100001];
int ans[100001];
void bfs(int x) {
vector<int> vec;
int clean = 0, dirty = 0;
queue<int> que;
que.push(x);
visited[x] = 1;
while (!que.empty()) {
int cur = que.front(); que.pop();
vec.emplace_back(cur);
if (water[cur]) clean++;
else dirty++;
for (auto& node : G[cur]) {
if (visited[node]) continue;
visited[node] = 1;
que.push(node);
}
}
if (clean > dirty) {
for (auto& n : vec) ans[n] = 1;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N, M, Q; cin >> N >> M >> Q;
for (int n = 1; n <= N; n++) cin >> water[n];
while (M--) {
int x, y; cin >> x >> y;
G[x].emplace_back(y);
G[y].emplace_back(x);
}
for (int n = 1; n <= N; n++) {
if (visited[n]) continue;
bfs(n);
}
while (Q--) {
int x; cin >> x;
cout << ans[x] << '\n';
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 25189 // C++] 시니컬한 개구리 (0) | 2022.08.20 |
---|---|
[BOJ 25188 // C++] 1, 3, 모 나누기 (0) | 2022.08.19 |
[BOJ 17020 // C++] Train Tracking 2 (0) | 2022.08.17 |
[BOJ 6137 // C++] 문자열 생성 (0) | 2022.08.16 |
[BOJ 5623 // C++] 수열의 합 (0) | 2022.08.15 |