https://leetcode-cn.com/problems/is-graph-bipartite/
解题:38 min
题解:28 min
给定一个无向图graph,当这个图为二分图时返回true。
如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。
graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到graph.length-1之间的整数。这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值。
经典问题,交叉染色法判断二分图。假设有两种颜色,比如 黑色和白色,首先将任意一个节点染为黑色,然后将与它相连的节点染为白色,接着继续遍历染为白色的节点,将与它们相连的节点染为黑色,以此类推(将相连的节点染成与当前节点不同的颜色),直到某一次染色时,将要染色的节点当前已染的颜色 与 将要染上的颜色不同,那么这不是二分图,如果所有节点都可以无矛盾的染上颜色,那么这是二分图。
本题的图不一定联通,所以一次BFS遍历完还需试试有无未染色的节点。
时间复杂度: O ( V + E ) O(V+E) O(V+E)
看完题解以后,我觉得我的写法有点傻,根本不用每次BFS完都全部遍历找未被染色的节点,之前染过色的节点一定有颜色啊,顺序解决就好了啊 宛如智障,所以我改了
class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
int V = graph.size();
vector<int> color(V, -1); // -1 uncolored, 0 black, 1 white
queue<int> q;
for(int i = 0; i < V; ++i) {
if(color[i] == -1) {
q.push(i);
color[i] = 0;
while(!q.empty()) {
int now = q.front();
q.pop();
for(int j = 0; j < graph[now].size(); ++j) {
if(color[graph[now][j]] == color[now]) {
return false;
}
if(color[graph[now][j]] == -1) {
color[graph[now][j]] = !color[now];
q.push(graph[now][j]);
}
}
}
}
}
return true;
}
};