[알고리즘문제]
[백준] 11724번 : 연결 요소의 개수
whatezlife
2025. 2. 26. 08:36
연결 요소의 개수 성공
시간 제한메모리 제한제출정답맞힌 사람정답 비율
3 초 | 512 MB | 155372 | 70478 | 46091 | 42.203% |
문제
방향 없는 그래프가 주어졌을 때, 연결 요소 (Connected Component)의 개수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 정점의 개수 N과 간선의 개수 M이 주어진다. (1 ≤ N ≤ 1,000, 0 ≤ M ≤ N×(N-1)/2) 둘째 줄부터 M개의 줄에 간선의 양 끝점 u와 v가 주어진다. (1 ≤ u, v ≤ N, u ≠ v) 같은 간선은 한 번만 주어진다.
출력
첫째 줄에 연결 요소의 개수를 출력한다.
예제 입력 1 복사
6 5
1 2
2 5
5 1
3 4
4 6
예제 출력 1 복사
2
예제 입력 2 복사
6 8
1 2
2 5
5 1
3 4
4 6
5 4
2 4
2 3
예제 출력 2 복사
1
package 문제11724연결요소의개수;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;
public class Main {
static List<Integer>[] arr;
static int N;
static boolean[] visited;
public static void main(String[] args) throws IOException {
System.setIn(new FileInputStream("res/문제11724연결요소의개수.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
StringTokenizer st = new StringTokenizer(s);
N = Integer.parseInt(st.nextToken()); // 1<=N<=1000
int M = Integer.parseInt(st.nextToken()); // 0<=M<=N(N-1)/2 (하나도 없거나 전부 연결하거나 가능)
arr = new ArrayList[N + 1];
visited = new boolean[N+1];
for (int i = 0; i <= N; i++) {
arr[i] = new ArrayList<>();
}
for (int i = 0; i < M; i++) {
s = br.readLine();
st = new StringTokenizer(s);
int A = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
arr[A].add(B);
arr[B].add(A);
} // 입력
int count = 0;
for (int i =1; i<=N; i++) {
if (visited[i]!=true && !arr[i].isEmpty()) {
dfs(i);
count++;
}
else if (visited[i]!=true && arr[i].isEmpty()) {
count++; // 어느 노선에도 연결되지 않은 경우
}
}
System.out.println(count);
}
public static void dfs(int A) {
Stack<Integer> stack = new Stack<>();
stack.add(A);
visited[A] = true;
while(!stack.isEmpty()) {
int num = stack.pop();
for (int n : arr[num]) { // 스택에 집어 넣고 방문 처리
if (visited[n] !=true) { // 방문한 적이 없다면
stack.add(n);
visited[n] = true;
}
}
}
return;
}
}
🔴 틀린 부분 요약 & 해결 방법 (2번이 찐 틀린 이유)
1️⃣ DFS를 구현한다고 했지만, BFS처럼 구현됨
- 문제점: Queue → Stack으로 바꿨지만, DFS의 핵심인 시작 노드 방문 체크를 안 함
- 해결 방법:
- stack.add(A); (초기 노드부터 스택에 넣기)
- visited[A] = true; (초기 노드 방문 처리하기)
2️⃣ 연결 요소 개수를 세는 조건이 잘못됨
- 문제점: !arr[i].isEmpty() 조건을 걸어서 고립된 노드(간선 없는 노드)를 체크하지 못함
- 해결 방법:
- if (!visited[i]) { dfs(i); count++; }
- 그냥 방문하지 않은 노드만 체크하면 됨!
3️⃣ DFS 호출 전에 visited 체크를 실수함
- 문제점:
java복사편집if (visited[i] != true && !arr[i].isEmpty()) { dfs(i); count++; } else if (visited[i] != true && !arr[i].isEmpty()) { count++; }
- !arr[i].isEmpty()를 체크하는 바람에 고립된 노드를 세지 못함.
- else if 조건이 잘못됨 (!arr[i].isEmpty() → arr[i].isEmpty())
- 해결 방법:
- if (!visited[i]) { dfs(i); count++; } 이 한 줄로 해결됨!
✅ 앞으로 실수 안 하려면 꼭 기억할 것!
✔ DFS/BFS를 구현할 때 "시작 노드 방문 체크" 필수!
✔ 연결 요소 개수 셀 때는 "방문 여부만 확인"하면 됨!
✔ 고립된 노드도 체크해야 하므로 arr[i].isEmpty() 같은 조건 쓰지 말 것!