문제

https://www.acmicpc.net/problem/11724


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

int[] nm = convertStringArrayToIntegerArray(br.readLine().split(" "));
int n = nm[0];
int m = nm[1];

boolean[][] graph = new boolean[n+1][n+1];
while (m-- > 0) {
int[] xy = convertStringArrayToIntegerArray(br.readLine().split(" "));

graph[xy[0]][xy[1]] = true;
graph[xy[1]][xy[0]] = true;
}

int answer = 0;

boolean[] isVisit = new boolean[n+1];
for (int i = 1; i < graph.length; i++) {
if (!isVisit[i]) {
answer += bfs(isVisit, graph, i);
}
}

System.out.println(answer);
}

private static int[] convertStringArrayToIntegerArray(String[] args) {
int[] array = new int[args.length];
int i = 0;
for (String str : args) {
array[i++] = Integer.parseInt(str);
}

return array;
}

private static int bfs(boolean[] isVisit, boolean[][] graph,int startIndex) {
Queue<Integer> queue = new LinkedList<>();
queue.offer(startIndex);
isVisit[startIndex] = true;

while (!queue.isEmpty()) {
int x = queue.poll();

for (int i = 1; i < isVisit.length; i++) {
if (isVisit[i]) {
continue;
}

if (graph[x][i]) {
queue.offer(i);
isVisit[i] = true;
}
}
}

return 1;
}

흐름

  1. 그래프의 연결 관계를 인접행렬로 만들기 위해 정점의 개수 + n한 크기의 2차원 배열을 만들고,
  2. 이 문제에서 그래프는 방향이 없는 무방향 그래프이기 때문에 a->b로 가는 간선이 있으면 b->a로 가는 간선도 있는 것이므로 대칭이 되도록 배열에 저장한다.
  3. 이후 정점의 개수만큼 루프 돌면서 연결요소의 개수를 구하는데 아직 간선이 연결되지 않은 정점일 경우에만 BFS 탐색을 통해 탐색한다.
  4. queue를 이용해 bfs를 구현하는데 우선 탐색이 시작되는 정점의 index를 queue에 저장하고, isVisit[] 변수에도 true로 해당 index를 탐색했다고 저장한다.
  5. queue가 빌 때 까지 반복하면서 queue에 저장된 index를 poll한다.
  6. 정점의 개수 만큼 반복하면서 이미 연결된 정점이면 넘어가고
  7. 아직 연결되지 않은 정점이면서 다른 정점과 연결된 정점이면 queue에 해당 index를 저장하고, 방문했으니 true도 저장한다.
  8. queue가 비어 루프가 종료되면 연결 요소 하나가 완성된 것이므로 1을 return 하고 bfs를 종료한다.
  9. return된 1들을 저장해 모든 정점을 탐색 후 종료한다.

결과


참고 사이트