886. 可能的二分法
本题比较巧妙,只是要求分成两组,对于每一个成员i,他讨厌的人都在另一个集合中。因为只有两个集合,不妨给每个点都设置“反向点”,如果x和y的反向点在一个集合内,说明x和y不能在一个集合内。
当a讨厌b时,b应该在另一个集合,那么b + n就和a在一个集合中,采用merge操作,a + n就和b在一个集合中,同理。
就这样,对于每一个dislike,都可以merge两次,如果后续dislike的两个点在同一个集合,则返回false。
举个例子,[1, 2], [1, 3], [2, 3]:可知2、3都和1的反向点4在同一个集合中,这说明它们都不能和1在一个集合,然后[2, 3]来了,要求它们又不能在一个集合,显然不能满足。
function merge(fa, a, b) {
const f1 = find(fa, a);
const f2 = find(fa, b);
fa[f2] = f1;
}
function find(fa, x) {
return fa[x] === x ? x : (fa = find(fa, fa[x]));
}
var possibleBipartition = function (n, dislikes) {
const fa = Array(2 * n + 1).fill(0);
for (let i = 1; i <= 2 * n; i++) {
fa[i] = i;
}
for (const [a, b] of dislikes) {
if (find(fa, a) === find(fa, b)) {
return false;
}
merge(fa, a, b + n);
merge(fa, b, a + n);
}
console.log(fa);
return true;
};