백준 11724번 "연결 요소의 개수" 문제를 풀어보겠습니다. 방향 없는 그래프에서 연결 요소(Connected Component)의 개수를 구하는 기본적인 그래프 탐색 문제입니다.
문제 요약:
연결 요소란 서로 연결된 정점들의 집합을 의미합니다. 모든 정점을 순회하면서 아직 방문하지 않은 정점에서 DFS를 시작할 때마다 새로운 연결 요소를 발견한 것입니다.
#include <bits/stdc++.h>
using namespace std;
bool vis[100001];
vector<vector<int>> g(100001);
int cnt = 0;
void dfs(int cur){
vis[cur] = true;
for(auto nxt : g[cur]){
if(vis[nxt]) continue;
dfs(nxt);
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int v, e;
cin >> v >> e;
for(int i = 0; i < e; i++){
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a); // 무방향 그래프이므로 양방향 추가
}
for(int i = 1; i <= v; i++){
if(!vis[i]){
cnt++;
dfs(i);
}
}
cout << cnt;
return 0;
}
처음에는 이렇게 작성했었습니다:
// 잘못된 코드
for(int i = 1; i < e; i++){ // 첫 번째 간선 건너뛰고, 마지막 간선 누락
// ...
}
for(int i = 1; i < v; i++){ // 마지막 정점 v 누락
// ...
}
문제점:
해결책:
for(int i = 0; i < e; i++){ // 0부터 e-1까지 (총 e개)
for(int i = 1; i <= v; i++){ // 1부터 v까지 (모든 정점)
문제에서 정점 번호가 1부터 시작하는데, 처음에는 0부터 확인해서 틀렸습니다.
// 잘못된 코드
for(int i = 0; i < v; i++){ // 정점 0 확인 (존재하지 않음)
정점 0은 실제로 존재하지 않지만 방문하지 않은 상태로 카운트되어 연결 요소 개수가 +1 되는 문제가 발생했습니다.
그래프 탐색 문제에서는 인덱스 범위를 정확히 파악하는 것이 중요합니다. 특히 문제에서 정점 번호가 몇 번부터 시작하는지, 몇 개의 데이터를 입력받아야 하는지 꼼꼼히 확인해야 합니다.
DFS를 이용한 연결 요소 찾기는 그래프 이론의 기본이 되는 중요한 개념이므로, 이 패턴을 잘 익혀두면 다른 그래프 문제에도 응용할 수 있을 것입니다.