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