https://leetcode-cn.com/problems/possible-bipartition/
给定一组 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]
思路,这种不喜欢会形成一个圈,使用dfs检查这个圈内人员编号01着色,不冲突就ok。然后再检测下一个圈。(有点循环节的感觉)
存在问题
1.dfs检测的时候color向量是从1开始,所以需要多开一个。
2.在dfs里面,first和second都要进行检测。
class Solution {
public:
bool isok=true;
bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
vector<int> color(N+1,-1);
int n=dislikes.size();
bool ischage;
do
{ ischage=false;
for(int i=0; i<n; i++)
{
if(color[dislikes[i][0]]==-1)
{
color[dislikes[i][0]]=0;
dfs(color,dislikes,dislikes[i][0]);
ischage=true;
break;
}
}
} while(ischage);
return isok;
}
void dfs(vector<int> & color,vector<vector<int>>& dislikes,int t)
{
int n=dislikes.size();
if(!isok) return;
for(int i=0; i<n; i++)
{
// 第一个是
if(dislikes[i][0]==t)
{
if(color[dislikes[i][1]]==-1)
{
color[dislikes[i][1]]=1-color[t];
dfs(color,dislikes,dislikes[i][1]);
}
else if(color[dislikes[i][1]]>=0&&color[dislikes[i][1]]!=1-color[t])
{
isok=false;
return;
}
}
// 第二个是
if(dislikes[i][1]==t)
{
if(color[dislikes[i][0]]==-1)
{
color[dislikes[i][0]]=1-color[t];
dfs(color,dislikes,dislikes[i][0]);
}
else if(color[dislikes[i][0]]>=0&&color[dislikes[i][0]]!=1-color[t])
{
isok=false;
return;
}
}
}
}
};
题目给的一般解法。图中邻接表思想
class Solution {
public:
bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
int first,second;
vector<int>color(N+1,-1);
vector<vector<int> >adj(N+1);
for(int i=0; i<dislikes.size(); i++) {
first=dislikes[i][0];
second=dislikes[i][1];
adj[first].push_back(second);
adj[second].push_back(first);
}
for(int i=1; i<=N; i++)
if(color[i]==-1&&!dfs(adj,i,color,1))return false;
return true;
}
bool dfs( vector<vector<int> >&adj,int n,vector<int>&color,int C) {
if(color[n]!=-1) {
return color[n]==C;
}
color[n]=C;
for(int next:adj[n]) {
if(!dfs(adj,next,color,1-C))return false;
}
return true;
}
};