先说一下二分图的定义:
1.两个子集内的顶点都不相交
2.两个点集包含了所有点
用了两种图的遍历方法,其实都是染色法,解释都在注释里
法一:BFS
class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
//1.两个子集内的顶点都不相交
//2.两个点集包含了所有点
//两个连通的顶点要放到不同集合里,如果同一个集合的顶点是连通的直接false
//起点红色,相邻结点绿色,绿色的相邻结点红色
//我们在染色的过程中,如果要给某个结点上色,那个结点已经有颜色,而且颜色还和我们企图上的不一样,就是false
vector<int> color(graph.size(),0);//0就是无色,1就是红色,2就是绿色
queue<int> q;
//遍历每个点,对其进行bfs
for(int i = 0; i < graph.size(); ++i){
//如果这个点没有上过色,就对其进行上色,上为1
if(color[i] == 0){
q.push(i);
color[i] = 1;
while(!q.empty()){
//图的层序遍历和树不一样,不用记录size
//直接通过这个点的连接节点来控制层就行了
int topNode = q.front();
q.pop();
int wantColor = color[topNode] == 1?2:1;
for(int x : graph[topNode]){
if(color[x] == 0){
color[x] = wantColor;
q.push(x);
}
else if(color[x] != wantColor) return false;
}
}
}
}
return true;
}
};
法二:DFS
class Solution {
public:
void dfs(int index, vector<vector<int>>& graph, vector<int>& color, int wantColor){
if(color[index] != 0 ){
if(color[index] != wantColor){
res = false;
}
return;
}
if(res == false) return;
color[index] = wantColor;
wantColor = color[index] == 1?2:1;
for(int x : graph[index]){
dfs(x,graph,color,wantColor);
}
}
bool isBipartite(vector<vector<int>>& graph) {
//DFS,遍历每个顶点,一直往下搜就完事了
vector<int> color(graph.size(),0);
for(int i = 0; i < graph.size() && res != false; ++i){
//不要盲目给结点上红色,要在这个结点没上色的情况下才给它上色
if(color[i] == 0){
dfs(i,graph,color,1);
}
if(res == false) return false;
}
return res;
}
private:
bool res = true;
};