연결 요소의 개수 (백준 11724)
2023. 1. 2. 12:35
3초 | 512 MB |
문제
방향 없는 그래프가 주어졌을 때, 연결 요소 (Connected Component)의 개수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 정점의 개수 N과 간선의 개수 M이 주어진다. (1 ≤ N ≤ 1,000, 0 ≤ M ≤ N×(N-1)/2) 둘째 줄부터 M개의 줄에 간선의 양 끝점 u와 v가 주어진다. (1 ≤ u, v ≤ N, u ≠ v) 같은 간선은 한 번만 주어진다.
출력
첫째 줄에 연결 요소의 개수를 출력한다.
<생각의 흐름>
제한시간 3초, N은 최대 1000 -> O(n^2) 알고리즘 사용해도 될 듯
연결 요소는 에지로 연결된 노드의 집합이며, 한번의 DFS가 끝날 때까지 탐색한 모든 노드의 집합을 하나의 연결 요소로 판단할 수 있음
즉 DFS로 돌면서 방문배열에 대해서 true로 바꾸고 끝까지 돌면 될듯??
우선 인접리스트로 그래프를 구현해보자 + 방문 배열도 필요
DFS의 수행횟수가 연결 요소 갯수이다.
<코드>
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Main {
static boolean visited[];
static ArrayList<Integer>[] A; // 가중치 있을 때는 <Node>
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
visited = new boolean[n+1]; // 0번 인덱스는 안씀
A = new ArrayList[n+1];
for(int i = 1; i < n+1 ; i++){
A[i] = new ArrayList<Integer>();
}
for(int i = 0; i < m ; i++){
st = new StringTokenizer(br.readLine());
int s = Integer.parseInt(st.nextToken()); // 시작점
int e = Integer.parseInt(st.nextToken()); // 종료점
A[s].add(e); // 방향없을 때는 양쪽다 해줘야함 (중요!)
A[e].add(s);
}
int count = 0;
for(int i = 1; i < n+1 ; i++) {
if(!visited[i]){ // 방문안한곳이면
count++;
DFS(i);
}
}
System.out.println(count);
}
private static void DFS(int v) { // 재귀
if(visited[v]){
return;
}
visited[v] = true;
for(int i : A[v]){
if(!visited[i]){
DFS(i);
}
}
}
}
<피드백>
우선 static 변수로 방문 배열과 그래프를 표현할 인접리스트를 선언한다.
static boolean visited[];
static ArrayList<Integer>[] A; // 가중치 있을 때는 <Node>
ArrayList 배열의 원소 하나당 또 ArrayList를 넣어줘야함
visited = new boolean[n+1]; // 0번 인덱스는 안씀
A = new ArrayList[n+1];
for(int i = 1; i < n+1 ; i++){
A[i] = new ArrayList<Integer>();
}
시작점과 종료점을 입력받아서 입력해준다.
for(int i = 0; i < m ; i++){
st = new StringTokenizer(br.readLine());
int s = Integer.parseInt(st.nextToken()); // 시작점
int e = Integer.parseInt(st.nextToken()); // 종료점
A[s].add(e); // 방향없을 때는 양쪽다 해줘야함 (중요!)
A[e].add(s);
}
DFS 메서드 구현
private static void DFS(int v) { // 재귀
if(visited[v]){
return;
}
visited[v] = true;
for(int i : A[v]){
if(!visited[i]){
DFS(i);
}
}
}
'코테뿌수기 - java > 문제 풀기' 카테고리의 다른 글
수 찾기 (백준 1920) (0) | 2023.01.02 |
---|---|
미로 탐색 (백준 2178) (0) | 2023.01.02 |
소트인사이드 (백준 1427) (0) | 2023.01.01 |
수 정렬하기 (백준 2750) (0) | 2023.01.01 |
절댓값 힙 (백준 11286) (0) | 2023.01.01 |