문제: 거짓말
분류: 자료 구조, 그래프 이론, 그래프 탐색, 분리 집합
난이도: 골드4
Union-Find 알고리즘을 사용한다.
M)이다.const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "input.txt";
let [NM, knowInfo, ...partyInfo] = fs
.readFileSync(filePath)
.toString()
.trim()
.split("\n");
const [N, M] = NM.split(" ").map(Number);
const [knowCnt, ...knowNum] = knowInfo.split(" ").map(Number);
partyInfo = partyInfo.map((info) => info.split(" ").slice(1).map(Number));
let root = Array.from({ length: N + 1 }, (_, i) => i);
const find = (x) => {
if (x === root[x]) return x;
return (root[x] = find(root[x]));
};
const union = (x, y) => {
x = find(x);
y = find(y);
if (x != y) root[y] = x;
};
// 파티에 참가하는 첫 번째 사람과 나머지 사람들을 모두 union한다.
partyInfo.forEach((info, idx) => {
info.forEach((i) => {
union(partyInfo[idx][0], i);
});
});
let answer = M;
for (let i = 0; i < M; i++) {
for (let j = 0; j < knowCnt; j++) {
// 파티에 참가하는 첫 번째 사람과 진실을 아는 사람의 root가 같다면
// 하나 이상의 같은 파티에 참가한다는 뜻이므로 정답을 감소시킨다.
if (find(partyInfo[i][0]) === find(knowNum[j])) {
answer--;
break;
}
}
}
console.log(answer);