※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 25172번 문제인 꼼꼼한 쿠기의 졸업여행이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/25172
25172번: 꼼꼼한 쿠기의 졸업여행
첫번째 줄에는 여행지도에 있는 관광지의 수 N(1 ≤ N ≤ 200,000)와 두 관광지 사이를 연결하는 길의 수 M(1 ≤ M ≤ min(N×(N-1)/2, 200,000))가 주어진다. 다음 M개의 줄에는 쿠기가 그린 여행지도에서 각
www.acmicpc.net
주어진 그래프에서 직접 노드를 하나씩 지워나가는 방식으로는 문제를 해결하기 어렵다. 대신, 그래프를 지워나가는 과정을 거꾸로 살펴 현재의 그래프로 채워나가는 과정으로 문제를 해결하자. 이는 disjoint set을 이용하여 편하게 구현할 수 있다.
구체적으로, 이번 i번째에 추가되는 노드가 x라 하면 지금까지 추가된 노드 중 x와 연결된 노드들을 disjoint set 자료구조를 x에 합치면서 x와 연결된 노드들의 개수를 같이 관리한다. 이 개수가 i와 같다면 현재 모든 노드들은 연결되어 있는 것이고 아니라면 연결되어있지 않은 상태라고 판단할 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
int N, M;
int uf[200001];
int cnt[200001];
int findf(int x) {
if (x == uf[x]) return x;
return uf[x] = findf(uf[x]);
}
vector<int> G[200001];
vector<bool> ans;
vector<int> qry;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M;
while (M--) {
int x, y; cin >> x >> y;
G[x].emplace_back(y);
G[y].emplace_back(x);
}
ans.emplace_back(0);
for (int i = 1; i <= N; i++) {
int x; cin >> x;
qry.emplace_back(x);
}
for (int i = 1; i <= N; i++) {
int x = qry.back(); qry.pop_back();
uf[x] = x, cnt[x] = 1;
for (auto& node : G[x]) {
if (uf[node]) {
int fnode = findf(node);
if (fnode == x) continue;
uf[fnode] = x;
cnt[x] += cnt[fnode];
}
}
if (cnt[x] == i) ans.emplace_back(1);
else ans.emplace_back(0);
}
while (!ans.empty()) {
if (ans.back()) cout << "CONNECT\n";
else cout << "DISCONNECT\n";
ans.pop_back();
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 1062 // C++] 가르침 (0) | 2022.08.23 |
---|---|
[BOJ 3055 // C++] 탈출 (0) | 2022.08.22 |
[BOJ 25171 // C++] 긴장한 아리와 쿠기의 카드게임 (0) | 2022.08.21 |
[BOJ 25170 // C++] 명랑한 아리의 외출 (0) | 2022.08.21 |
[BOJ 25165 // C++] 영리한 아리의 포탈 타기 (0) | 2022.08.21 |