[백준] 11724 연결 요소의 개수 JavaScript

·2024년 9월 11일

문제

방향 없는 그래프가 주어졌을 때, 연결 요소 (Connected Component)의 개수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 정점의 개수 N과 간선의 개수 M이 주어진다. (1 ≤ N ≤ 1,000, 0 ≤ M ≤ N×(N-1)/2) 둘째 줄부터 M개의 줄에 간선의 양 끝점 u와 v가 주어진다. (1 ≤ u, v ≤ N, u ≠ v) 같은 간선은 한 번만 주어진다.

출력

첫째 줄에 연결 요소의 개수를 출력한다.

예제 입력

6 5
1 2
2 5
5 1
3 4
4 6

예제 출력

2

내가 했던 풀이 방법


다음과 같을 때 하나의 그래프에 두 개의 연결 요소를 가진다고 한다. 즉 각각 나누어진 그래프의 개수를 찾아야 한다.

  1. graph를 인접행렬로 구현하여 연결된 노드들을 저장해준다.
  2. visited 배열을 모두 false로 두고 count를 0으로 초기화한다. 여기서 count가 연결 요소의 개수가 된다.
  3. 노드 1부터 순차적으로 해당 노드를 방문하지 않았다면, queue에 해당 노드를 넣어주고, BFS를 이용해 인접한 노드들을 찾아준다. queue의 length가 0이 된다면 연결 요소 하나를 모두 찾은 것이므로, count를 1 증가시켜준다. 이를 마지막 노드까지 반복한다.
  4. queue의 shift()를 여러번 반복하게 되면 효율성이 떨어지게 되므로, head 변수를 따로 두어 shift를 이용하지 않고 맨 앞의 노드를 가져올 수 있도록 구현해준다.

코드

const fs = require('fs');
let [n, ...edge] = fs.readFileSync(0, 'utf-8').toString().trim().split('\n');

let N = Number(n.trim().split(' ')[0]);
let M = Number(n.trim().split(' ')[1]);

let graph = Array.from({ length: N + 1 }, () => []);

for (let i = 0; i < M; i++) {
  let [node1, node2] = edge[i].trim().split(' ').map(Number);

  graph[node1].push(node2);
  graph[node2].push(node1);
}

let visited = Array.from({ length: N + 1 }, () => false);
let count = 0;

for (let i = 1; i <= N; i++) {
  if (!visited[i]) {
    let queue = [];
    let head = 0;
    queue.push(i);

    while (head < queue.length) {
      let current = queue[head++];
      visited[current] = true;
      for (let j = 0; j < graph[current].length; j++) {
        if (!visited[graph[current][j]]) {
          queue.push(graph[current][j]);
          visited[graph[current][j]] = true;
        }
      }
    }
    count++;
  }
}

console.log(count);

회고

알고리즘은 쉽게 생각했는데 시간초과/메모리초과를 다 당했다. 흑흑 최근에 BFS를 shift로도 풀 수 있는 문제들을 많이 풀어서 그런가 head를 사용하기 귀찮아졌다..ㅎ 정점 개수를 보고 shift가 안 될거라는 걸 생각했어야 했는데 안일했다.

profile
Frontend🍓

0개의 댓글