886. 可能的二分法(dfs bfs二部图判断)
给定一组 n
人(编号为 1, 2, ..., n
), 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。
给定整数 n
和数组 dislikes
,其中 dislikes[i] = [ai, bi]
,表示不允许将编号为 ai
和 bi
的人归入同一组。当可以用这种方法将所有人分进两组时,返回 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
class Solution { public: bool is_ok = true; void bfs(vector<bool>& colour, int start_node, vector<bool>&visted, vector<vector<int>>& graph) { queue<int> q; q.push(start_node); visted[start_node] = true; while(!q.empty()) { int sz = q.size(); for(int i = 0; i < sz; i++) { int top = q.front();q.pop(); for (auto adj : graph[top]) { if (visted[adj]) { // 判断颜色 if (colour[top]==colour[adj]) { is_ok = false; } } else { // 那么应该给节点 neighbor 涂上和节点 v 不同的颜色 colour[adj] = !colour[top]; q.push(adj); visted[adj] = true; } } } } } void dfs(vector<bool>& colour, int cur_node, vector<bool>&visted, vector<bool>& path, vector<vector<int>>& graph) { path[cur_node] = true; visted[cur_node] = true; for(auto adj : graph[cur_node]) { if (visted[adj]) { // 判断颜色 if (colour[cur_node]==colour[adj]) { is_ok = false; } } else { // 那么应该给节点 neighbor 涂上和节点 v 不同的颜色 colour[adj] = !colour[cur_node]; dfs(colour,adj,visted,path,graph); } } path[cur_node] = false; } bool possibleBipartition(int n, vector<vector<int>>& dislikes) { vector<vector<int>> graph = vector<vector<int>>(n+1,vector<int>()); for(auto vec:dislikes) { graph[vec[0]].emplace_back(vec[1]); graph[vec[1]].emplace_back(vec[0]); } vector<bool> colour = vector<bool>(n+1,true); vector<bool> visted = vector<bool>(n+1,false); vector<bool> path = vector<bool>(n+1,false); // 因为图不一定是联通的,可能存在多个子图 // 所以要把每个节点都作为起点进行一次遍历 // 如果发现任何一个子图不是二分图,整幅图都不算二分图 for (int i = 1; i <= n;i++) { if (visted[i]) continue; //dfs(colour,i,visted,path,graph); bfs(colour,i,visted,graph); } return is_ok; } };