886. 可能的二分法
给定一组 N 人(编号为 1, 2, …, N), 我们想把每个人分进任意大小的两组。
每个人都可能不喜欢其他人,那么他们不应该属于同一组。
形式上,如果 dislikes[i] = [a, b],表示不允许将编号为 a 和 b 的人归入同一组。
当可以用这种方法将每个人分进两组时,返回 true;否则返回 false。
示例 1:
输入:N = 4, dislikes = [[1,2],[1,3],[2,4]]
输出:true
解释:group1 [1,4], group2 [2,3]
示例 2:
输入:N = 3, dislikes = [[1,2],[1,3],[2,3]]
输出:false
示例 3:
输入:N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
输出:false
提示:
1 <= N <= 2000
0 <= dislikes.length <= 10000
1 <= dislikes[i][j] <= N
dislikes[i][0] < dislikes[i][1]
对于 dislikes[i] == dislikes[j] 不存在 i != j
分析:
本题就是直接使用DFS(或BFS)进行模拟。将所有人分为两组,就是给所有人在0,1两种颜色上着色,使其不冲突。
首先所有的节点都没有着色,标记为-1。
对任意的联通分量,第一个节点我们可以随意着色,(着色为1),然后进行DFS对其他相邻的节点进行着色。
若该节点没有被着色,则将其着色为另外一种颜色,并递归对其相邻节点进行着色。
若该节点已经着色,则只需判断这两个相邻的节点的颜色是否相同,相同则存在冲突。
AC代码:
class Solution {
public:
int c[2019];
vector<int> e[2019];
int dfs(int id,int color)
{
c[id] = color;
int ans = 1;
for(int i=0;i<e[id].size();i++)
{
if(c[e[id][i]] == -1) ans &= dfs(e[id][i],color^1);
else if(c[e[id][i]] == color)
{
ans = 0;
break;
}
}
return ans;
}
bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
if(N<=2) return true;
memset(c,-1,sizeof(c));
int m = dislikes.size();
for(int i=0;i<m;i++)
{
e[dislikes[i][0]].push_back(dislikes[i][1]);
e[dislikes[i][1]].push_back(dislikes[i][0]);
}
int ans = 1;
for(int i=1;i<=N;i++)
{
if(c[i] == -1)
ans &= dfs(i,1);
}
return ans;
}
};