※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 3261번 문제인 TOWER이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/3261
3261번: TOWER
In the first line of input there are two integers N and M, 2 ≤ N ≤ 10000, 0 ≤ M ≤ 100000. N is the number of glasses standing at the table and M is the number of moves to be made. Next M lines contain moves to be made. In each of those lines are tw
www.acmicpc.net
a번 컵이 포함된 모음과 b번 컵이 포함된 모음이 서로 다른 경우 a→b와 같은 작업을 하면 두 모음이 하나의 모음으로 합쳐지게 된다. 또한 서로 같은 모음에 들어있을 경우 해당 작업으로 컵의 모음이 변하지 않는다.
각 컵을 노드로 생각하고 a→b 작업을 a번 컵 노드와 b번 컵 노드 사이에 에지를 긋는 것으로 생각해보자. 이 때 a번 컵과 b번 컵이 같은 컵 모음에 들어있는지의 여부는 그래프 위에서 서로 같은 component에 속해있는지의 여부로 생각할 수 있음을 알 수 있다.
위의 관찰을 이용하면 각 a→b 연산에 대응되는 에지를 갖는 그래프에서 가장 큰 두 component에 속한 원소를 하나씩 출력하는 것으로 문제를 해결할 수 있음을 알 수 있다.
해당 그래프가 연결그래프여도(component가 유일하더라도) 유효한 move를 출력해주어야 함에 유의하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
int N, M;
vector<int> G[10001];
bool visited[10001];
int dfs(int cur) {
int ret = 1;
visited[cur] = 1;
for (auto& nxt : G[cur]) {
if (visited[nxt]) continue;
ret += dfs(nxt);
}
return ret;
}
int ans1 = 1, cnt1, ans2 = 1, cnt2;
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);
}
for (int i = 1; i <= N; i++) {
if (visited[i]) continue;
int cnt = dfs(i);
if (cnt >= cnt1) {
ans2 = ans1, cnt2 = cnt1;
ans1 = i, cnt1 = cnt;
}
else if (cnt > cnt2) ans2 = i, cnt2 = cnt;
}
cout << ans1 << ' ' << ans2;
}
'BOJ' 카테고리의 다른 글
[BOJ 2508 // C++] 사탕 박사 고창영 (0) | 2023.11.11 |
---|---|
[BOJ 2097 // C++] 조약돌 (0) | 2023.11.10 |
[BOJ 2002 // C++] 추월 (0) | 2023.11.08 |
[BOJ 28294 // C++] 프랙탈 (0) | 2023.11.07 |
[BOJ 28293 // C++] 자릿수 (0) | 2023.11.06 |