题解:
class Solution {
private:
// BFS
bool setColor(vector<vector<int>>& graph, vector<int>& colors, int i) {
colors[i] = 0;
queue<int> que;
que.push(i);
while (!que.empty()) {
int v = que.front();
que.pop();
for (auto& neb : graph[v]) {
// 已着色,但是不符合一条边两个节点不同颜色的要求
if (colors[neb] >= 0) {
if (colors[neb] == colors[v]) {
return false;
}
}
// 未着色,按照要求着色
else {
que.push(neb);
colors[neb] = 1 - colors[v];
}
}
}
return true;
}
public:
bool isBipartite(vector<vector<int>>& graph) {
vector<int> colors(graph.size(), -1);
for (int i = 0; i < graph.size(); ++i) {
if (colors[i] == -1) {
if (!setColor(graph, colors, i)) {
return false;
}
}
}
return true;
}
};
class UnionFind {
public:
UnionFind():_count(0) {
}
void add(int p) {
if (_father.find(p) != _father.end()) {
return;
}
_father[p] = p;
++_count;
}
int get_count() {
return _count;
}
bool is_connected(int p, int q) {
return find(p) == find(q);
}
void merge(int p, int q) {
int p_root = find(p);
int q_root = find(q);
if (p_root != q_root) {
_father[p_root] = q_root;
--_count;
}
}
private:
int find(int p) {
int root = p;
while (_father[root] != root) {
root = _father[root];
}
while (_father[p] != p) {
int ori = _father[p];
_father[p] = root;
p = ori;
}
return root;
}
public:
std::unordered_map<int, int> _father;
int _count;
};
class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
if (graph.size() <= 0) {
return false;
}
UnionFind uf;
int m = graph.size();
for (int i = 0; i < m; ++i) {
uf.add(i);
// 将当前节点,所有相邻的节点组成一个集合
for (int j = 0; j < graph[i].size(); ++j) {
uf.add(graph[i][j]);
// 如果当前节点已经和对方定点,已经在一个集合了,则不能构成二分图
if (uf.is_connected(i, graph[i][j])) {
return false;
}
// 相邻边构成集合
uf.merge(graph[i][0], graph[i][j]);
}
}
return true;
}
};