题目简介:
给定一组 n
人(编号为 1, 2, ..., n
), 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。
给定整数 n
和数组 dislikes
,其中 dislikes[i] = [ai, bi]
,表示不允许将编号为 ai
和 bi
的人归入同一组。当可以用这种方法将所有人分进两组时,返回 true
;否则返回 false
。
示例 1:
1 2 3
| 输入:n = 4, dislikes = [[1,2],[1,3],[2,4]] 输出:true 解释:group1 [1,4], group2 [2,3]
|
示例 2:
1 2
| 输入:n = 3, dislikes = [[1,2],[1,3],[2,3]] 输出:false
|
提示:
1 <= n <= 2000
0 <= dislikes.length <= 10^4
dislikes[i].length == 2
1 <= dislikes[i][j] <= n
ai < bi
dislikes
中每一组都 不同
思路:
使用并查集,初始化假设每个人只能和自己分到一起(每个人的祖先都是自己)。
然后依次遍历每个人不喜欢的人,若自己与不喜欢的人分到了一起(祖先相同),则返回false
。
否则,将其不喜欢的人都分到同一组(祖先都为同一个)。
若最后无冲突,则返回true
。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Solution { public: bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
vector<int> p(n + 1); iota(p.begin(), p.end(), 0);
function<int(int)> find = [&](int x) -> int { if (p[x] != x) p[x] = find(p[x]); return p[x]; };
vector<vector<int>> graph(n + 1, vector<int>()); for(int i = 0; i < dislikes.size(); i++){
graph[dislikes[i][0]].push_back(dislikes[i][1]); graph[dislikes[i][1]].push_back(dislikes[i][0]); }
for(int i = 0; i < n; i++){
for(int j = 0; j < graph[i + 1].size(); j++){
if(find(i + 1) == find(graph[i + 1][j])) return false; p[find(graph[i + 1][j])] = find(graph[i + 1][0]); } }
return true; } };
|