PS
11724. 연결 요소의 개수
tose33
2020. 8. 4. 17:46
https://www.acmicpc.net/problem/11724
11724번: 연결 요소의 개수
첫째 줄에 정점의 개수 N과 간선의 개수 M이 주어진다. (1 ≤ N ≤ 1,000, 0 ≤ M ≤ N×(N-1)/2) 둘째 줄부터 M개의 줄에 간선의 양 끝점 u와 v가 주어진다. (1 ≤ u, v ≤ N, u ≠ v) 같은 간선은 한 번만 주��
www.acmicpc.net
그래프가 주어지고 그 그래프가 연결돼 있는지 분리돼 있는지 판단하고
분리되어 있으면 몇 개로 분리되어 있는지 알아내는 문제.
일단 그래프가 분리되있는지 하나로 돼있는지 판단해야 하는데 DFS로 (BFS로 해도 될 것 같다)
첫 번째 정점에서부터 탐색을 시작한다.
DFS로 탐색을 시작한다면 이어져있는 모든 정점을 방문하고 돌아올 것이고 방문된 정점은 모두 true로 mark가 돼있을 것이다.
그렇다면 DFS탐색을 한번 수행하고 돌아왔을 때 true로 mark 돼 있지 않은 정점이 있다면 그래프가 하나가 아닌 분리된 그래프라는 것일 것이다.
간선의 양 끝점 u와 v가 다음과 같다면
1 2
2 5
5 1
3 4
4 6
그래프는 다음과 같이 생겼을 것이다
DFS를 다음과 같이 돌리면
for(int i = 1; i <= n; i++) {
if(!mark[i]) { dfs(i); cnt++; }
}
1 - 2 - 5 탐색하고 돌아오고
1,2는 이미 방문했으므로 3에서부터 DFS를 수행한다.
3 - 4 - 6 탐색하고 돌아오고 보니 모든 정점을 방문했다.
새롭게 DFS 탐색할때마다 cnt값을 증가시키면 cnt가 그래프가 분리된 개수이다.
코드
더보기
import java.util.*;
public class Main {
// 간선 정보 저장할 edge
static ArrayList<Integer> edge[] = new ArrayList[1001];
// 방문여부 저장할 mark
static boolean mark[] = new boolean[1001];
// Dept First Search
static void dfs(int n) {
Stack<Integer> s = new Stack<Integer>();
s.push(n); mark[n] = true;
while(!s.empty()) {
int f = s.peek();
boolean none = true;
for(int x : edge[f]) {
if(mark[x] == false) {
s.push(x); mark[x] = true;
none = false;
break;
}
}
if(none) s.pop();
}
}
public static void main(String args[]) {
Scanner s = new Scanner(System.in);
int n = s.nextInt(); // 정점의 개수
int m = s.nextInt(); // 간선의 개수
int cnt = 0;
// 2차원 edge 생성
for(int i = 0; i <= n; i++) {
edge[i] = new ArrayList<Integer>();
}
// 간선정보 edge에 저장
for(int i = 0; i < m; i++) {
int t, f;
t = s.nextInt();
f = s.nextInt();
edge[f].add(t);
edge[t].add(f);
}
// 방문 가능 정점 여러개일때 번호가 작은것부터 방문하므로 정렬
for(int i = 1; i <= n; i++)
Collections.sort(edge[i]);
for(int i = 1; i <= n; i++) {
if(!mark[i]) { dfs(i); cnt++; }
}
System.out.println(cnt);
}
}