kakasoo

[node.js] dfs와 bfs ( 백준 1260번 ) 본문

프로그래밍/알고리즘 풀이

[node.js] dfs와 bfs ( 백준 1260번 )

카카수(kakasoo) 2021. 4. 9. 17:19
반응형
// 백준 1260번 DFS와 BFS를 풀었습니다.

const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

const input = [];
let n = 0;
let m = 0;
let start = 0;
rl.on("line", (line) => {
    if (!n) {
        [n, m, start] = line.split(" ").map(Number);
    } else {
        input.push(line);
        if (input.length === m) {
            main();
            process.exit();
        }
    }
});

const dfs = (start) => {
    visited[start] = true;
    answer.push(start);

    for (let i = 0; i < edge[start].length; i++) {
        const next = edge[start][i];
        if (next && !visited[next]) {
            dfs(next);
        }
    }
};

const bfs = (start) => {
    const queue = [];
    visited[start] = true;
    queue.push(start);
    answer.push(start);

    while (queue.length) {
        const cur = queue.shift();

        for (let i = 0; i < edge[cur].length; i++) {
            const next = edge[cur][i];
            if (next && !visited[next]) {
                queue.push(next);
                answer.push(next);
                visited[next] = true;
            }
        }
    }
};

let visited;
let edge;
let answer;

const main = () => {
    visited = new Array(n + 1).fill(false);
    edge = [];
    answer = [];
    for (let i = 1; i < n + 1; i++) {
        edge[i] = [];
    }

    input.forEach((el) => {
        const [from, to] = el.split(" ").map(Number);
        edge[from].push(to);
        edge[to].push(from);
    });

    edge.forEach((el) => {
        el.sort((a, b) => a - b);
    });

    dfs(start);
    console.log(answer.join(" "));

    visited = new Array(n + 1).fill(false);
    answer = [];

    bfs(start);
    console.log(answer.join(" "));
};

JavaScript여서 오히려 안 좋은 부분들이 좀 많이 보인다.
일단 입력을 받은 후에 dfs, bfs를 사용하다 보니, visited 라는 방문 체크 용도의 배열, 간선을 저장할 edge, 정답을 저장할 answer 등을 바깥에 저장해둬야 한다. ( 전역적으로. )
왜냐하면 자바스크립트는 입력을 받은 다음에 main를 실행 시켜야 하는데, 사실 이것 자체가 readline으로 생긴 부작용이기 때문이다.
JavaScript에서는 main() 이라고 할 만한 함수가 사실 없다.
그냥 처음부터 전역으로 하면 됐다.
그럼에도 readline이 입력 후에 함수를 실행하게 하기 때문에, main을 만든 것이다...

푸념은 이 정도로 하고,
dfs, bfs는 그냥 의미에 충실하게 만들었다.

처음에 입력을 받은 상태에서,

edge, visited를 초기화해주고 dfs에 넣어준다.
answer이 가능한 모든 방문을 저장하고 있을 테니 출력해준다. ( 다른 언어였다면 그 때 그 때 출력해주면 되었지만, 자바스크립트에서는 한 글자씩 출력이 번거롭기 때문에 answer을 만들었다. 근데 지금 생각해보면 그냥 버퍼 이용해서 출력해주는 게 차라리 간단했을 거 같다. )
bfs도 마찬가지다.
사실 dfs는 스택, bfs는 큐를 이용해야 하지만, 자바스크립트 배열은 워낙 만능인지라.

반응형