785. Is Graph Bipartite?

题目

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.

1
2
3
4
5
6
7
8
9
10
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}.

1
2
3
4
5
6
7
8
9
10
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].

解题思路

  • 本题给了无向图的边,判断这个图是否是一个二分图
  • 什么是二分图?

    二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。孤立点可以任意划分在A或B集合。

  • 解法:
    • 使用BFS + 染色法
    • BFS以未被染色且非孤立点的点作为BFS搜索的起点
    • 使用染色法,只使用两种颜色,将与该点相邻(存在一条边)且未被染色的点染成与其不同的颜色,假如相邻的点已被染色且颜色与该点相同,则证明该图不是二分图。

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 染色法 + BFS

class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
int num = graph.size();

bool colors[num] = {false};
int visited[num] = {0};

queue<int> q;

for(int i = 0; i < num; ++i) {
if(graph[i].size() > 0 && visited[i] == 0) {
q.push(i);
visited[i] = 1;

// bfs
while(!q.empty()) {
int top = q.front();
q.pop();
for(auto i : graph[top]) {
if(!visited[i]) {
visited[i] = 1;
colors[i] = !colors[top];
q.push(i);
}
if(colors[i] == colors[top])
return false;
}
}
}
}

return true;
}
};