# 算法设计与分析（五）

## Is Graph Bipartite?

### 1. 题目

Given an undirected graph, return true if and only if it is bipartite.

Recall that a graph is bipartite if we can split it’s set of nodes into two independent subsets A and B such that every edge in the graph has one node in A and another node in B.

The graph is given in the following form: graph[i] is a list of indexes j for which the edge between nodes i and j exists. Each node is an integer between 0 and graph.length - 1. There are no self edges or parallel edges: graph[i] does not contain i, and it doesn’t contain any element twice.

Example 1:
Input: [[1,3], [0,2], [1,3], [0,2]]
Output: true
Explanation:
The graph looks like this:
0----1
| |
| |
3----2
We can divide the vertices into two groups: {0, 2} and {1, 3}.
Example 2:
Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
Output: false
Explanation:
The graph looks like this:
0----1
| \ |
| \ |
3----2
We cannot find a way to divide the set of nodes into two independent subsets.

Note:

graph will have length in range [1, 100].
graph[i] will contain integers in range [0, graph.length - 1].
graph[i] will not contain i or duplicate values.
The graph is undirected: if any element j is in graph[i], then i will be in graph[j].

### 4. 算法步骤

• 广度优先遍历
• 从每个顶点开始，如果顶点没被染色，将顶点染色为-1并将当点push进队列中。
• 如果队列不空，取队首，将与队首有边的顶点染成与队首颜色数互为相反数的颜色；如果发现颜色数相同，结束整个过程，说明不能构成二分图。
• 成功第一个步骤确保所有的点被遍历到，因为有非连通图的情况。
• 所有点遍历完，返回true。
• 深度优先遍历
• 对每个点进行深度优先遍历。
• 在递归过程传递的参数是前一个顶点的相反数，确保有边相连的顶点染上不同颜色。
• 在递归过程发现同一条边相连的两个顶点颜色一样，递归结束，返回false。

### 5. 源码

• 5.1 广度遍历实现
class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
vector<int> color(graph.size(), 0);
queue<int> q;
for(int i = 0; i < graph.size(); i++) {
if(color[i] == 0) {
color[i] = -1;
q.push(i);
while(!q.empty()) {
int temp = q.front();
q.pop();
for(int j = 0; j < graph[temp].size(); j++) {
if(color[graph[temp][j]] == 0) {
color[graph[temp][j]] = 0 - color[temp];
q.push(graph[temp][j]);
}
if(color[temp] == color[graph[temp][j]]) {
return false;
}
}
}
}
}
return true;
}
};

• 5.2 深度遍历实现
class Solution {
public:
bool dfs(int source, vector<vector<int>>& graph, vector<int>& color, int current) {
color[source] = current;
for(int i = 0; i < graph[source].size(); i++) {
if(color[graph[source][i]] == current) {
return false;
}
if(color[graph[source][i]] == 0) {
bool b = dfs(graph[source][i], graph, color, -current);
if(!b) {
return false;
}
}
}
return true;
}

bool isBipartite(vector<vector<int>>& graph) {
vector<int> color(graph.size(), 0);
int c = 1;
for(int i = 0; i < graph.size(); i++) {
if(color[i] == 0) {
bool b = dfs(i, graph, color, c);
if(b == false) {
return false;
}
}
}
return true;
}
};