[백준] 효율적인 해킹(1325)
4 views
블로그 불러오는 중...

const input =
process.platform === "linux"
? require("fs").readFileSync("/dev/stdin").toString().split("\n")
: require("fs").readFileSync("./input.txt").toString().split("\n");
const [N, M] = input[0].split(" ").map(Number);
const graph = Array.from({ length: N + 1 }, () => []);
for (let i = 1; i <= M; i++) {
const [A, B] = input[i].split(" ").map(Number);
graph[B].push(A);
}
const dfs = (currentIndex) => {
let answer = 0;
const willVisit = [currentIndex];
const visited = Array(N + 1).fill(false);
visited[currentIndex] = true;
while (willVisit.length > 0) {
const current = willVisit.pop();
if (!graph[current]) continue;
for (let i = 0; i < graph[current].length; i++) {
const value = graph[current][i];
if (visited[value]) continue;
visited[value] = true;
answer = answer + 1;
willVisit.push(value);
}
}
return answer;
};
let maxCount = -1;
let answer = [];
for (let i = 1; i <= N; i++) {
const count = dfs(i);
if (count > maxCount) {
maxCount = count;
answer = [i];
} else if (count === maxCount) {
answer.push(i);
}
}
console.log(answer.join(" "));
해당 문제는 DFS 를 통해서 연결된 노드의 개수를 세면 된다.
“A가 B를 신뢰하는 경우에는 B를 해킹하면, A도 해킹할 수 있다는 소리다.”
이 문구를 보고 그래프는 B → A 형태로 저장 되게 하였다.
for (let i = 1; i <= M; i++) {
const [A, B] = input[i].split(" ").map(Number);
graph[B].push(A);
}
모든 정점(컴퓨터)에 대해 DFS 또는 BFS를 돌려서, 가장 많은 정점을 해킹할 수 있는 정점을 찾는 문제다.
컴퓨터 개수 만큼 DFS 를 돌려서, 최대인 경우만 저장하고,
모든 수를 오름차순대로 돌았으므로 최대 값을 저장한 배열을 출력하면 된다.
계속 시간초과 에러가 났는데, 두가지 이슈가 있었다.
객체로 그래프 저장했을 때 계속 시간초과
→ const graph = {} 로 했다가 시간초과 발생
→ 배열로 바꾸니까 해결되었다.
→ 이유는 해시 충돌이나 탐색 비용 때문으로 보임
// 객체 방식 (비추)
const graph = {};
if (graph[B]) { graph[B].push(A); }
else { graph[B] = [A]; }
불필요한 sort() 사용도 제거했음
→ 이미 오름차순으로 저장했으므로 의미 없음