leetcode---886. 可能的二分法【dfs】【1】

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;
		}

};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值