题目
给定一个无向图graph,当这个图为二分图时返回true。
如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。
graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到graph.length-1之间的整数。这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值。
示例1
输入:
[[1,3], [0,2], [1,3], [0,2]]
输出:
true
说明:
无向图如下:
0----1
| |
| |
3----2
我们可以将节点分成两组: {0, 2} 和 {1, 3}。
示例2
输入:
[[1,2,3], [0,2], [0,1,3], [0,2]]
输出:
false
说明:
无向图如下:
0----1
| \ |
| \ |
3----2
我们不能将节点分割成两个独立的子集。
注意
- graph 的长度范围为 [1, 100]。
- graph[i] 中的元素的范围为 [0, graph.length - 1]。
- graph[i] 不会包含 i 或者有重复的值。
- 图是无向的: 如果 j 在 graph[i]里边, 那么 i 也会在 graph[j]里边。
解法
- 对于两个有线相连的节点,不可能在同一个集合中
- 我们可以选择一个未染色节点,给他染红色,则和他相连的所有节点染绿色。再把那些绿色节点相连的节点染成红色,循环下去。
- 如果在染色的过程中,发现节点已经染色,且颜色与我们将要给它染上的颜色不相同,则不可能是个二分图。
具体操作dfs:
- 选择未染色节点,进入dfs
- dfs中的操作
- 给这个节点染色,定义和他相连节点的颜色(相反的颜色)
- 遍历和他相连的节点
- 如果未染色,则染相反的颜色,再进入dfs(和这个点相连的节点染色)
- 如果染色,且现有颜色和要染的颜色不同,则表示不是二分图
具体操作bfs:
- 选择未染色节点,改变颜色,创建队列,把该节点押入队列
- 队列不空时
- 取出第一个节点并弹出,定义和他相连节点的颜色(相反的颜色)
- 遍历和他相连的节点
- 如果未染色,则染相反的颜色,押入队列
- 如果染色,且现有颜色和要染的颜色不同,则表示不是二分图,返回
代码
DFS:
//dfs
#include <stdio.h>
#include <iostream>
#include <unordered_map>
#include <vector>
#include <queue>
using namespace std;
class Solution {
int nocolor = 0;
int red = 1; //红色为一类节点
int green = 2; //绿色为一类节点
vector<int> color; //定义节点颜色,区分节点
bool res ;//是否是二分图
public:
//返回值:void 参数:节点 颜色 图
void dfs(int node,int c,vector<vector<int>>& graph){
color[node] = c;//此节点染色
int nextcolor = c==red?green:red;//定义和此节点不同的颜色
for(int i=0;i<graph[node].size();i++)//此节点相连的节点
{
if(color[graph[node][i]] == 0)//未染色,进入循环
{
dfs(graph[node][i],nextcolor,graph);
if(res == false)
return;
}
else if(color[graph[node][i]]!=nextcolor)//已染色,但是和我们想染的不同
{
res = false;
return ;
}
}
}
bool isBipartite(vector<vector<int>>& graph) {
res = true;
color.assign(graph.size(),0);
for(int i = 0;i<graph.size()&&res;i++)
{
//选择未染色的节点
if(color[i]==0)
dfs(i, 1, graph);
}
return res;
}
};
int main()
{
vector<vector<int>> ga (4,vector<int>(2));
ga[0][0]=1; ga[0][1]=3;
ga[1][0]=0; ga[1][1]=2;
ga[2][0]=1; ga[2][1]=3;
ga[3][0]=0; ga[3][1]=2;
Solution s;
cout<<s.isBipartite(ga);
return 0;
}
BFS:
//bfs
#include <stdio.h>
#include <iostream>
#include <unordered_map>
#include <vector>
#include <queue>
using namespace std;
class Solution {
int nocolor = 0;
int red = 1;
int green = 2;
vector<int> color;
public:
bool isBipartite(vector<vector<int>>& graph) {
bool res = true;
int n = graph.size();
vector<int>color(n,0);
for(int i=0;i<n;i++)
{
if(color[i]==0)//未染色
{
color[i] = 1; //染色
queue<int> q;
q.push(i);
while(!q.empty())//和他相关的所有节点,都染色
{
int x = q.front();
q.pop();
int nextcolor = color[x]==red?green:red;//定义和他相连节点的颜色
for(int i=0;i<graph[x].size();i++)//和他相关的点
{
int tmp = graph[x][i];
if(color[tmp]==0)//为染色
{
color[tmp] = nextcolor;//染色
q.push(tmp);//押入队列,为了下次找到和他相关的节点再染色。
}
else if (color[tmp]!=nextcolor)
{
res = false;
return res;
}
}
}
}
}
return res;
}
};
int main()
{
vector<vector<int>> ga (4,vector<int>(2));
ga[0][0]=1; ga[0][1]=3;
ga[1][0]=0; ga[1][1]=2;
ga[2][0]=1; ga[2][1]=3;
ga[3][0]=0; ga[3][1]=2;
Solution s;
cout<<s.isBipartite(ga);
return 0;
}
今天也是爱zz的一天哦!