1 并查集
- 遍历每个节点对应的邻接点,将每个邻接点通过并查集聚类
- 同时检查顶点是否与邻接点被聚到1类,若是则不满足二分图性质
- 注意孤立点判断
class UnionFind {
public:
int count;
vector<int> parent, size;
UnionFind(int n) {
count = n;
parent.resize(n);
size.resize(n);
for (int i = 0; i < n; i++) {
parent[i] = i;
size[i] = 1;
}
}
void unite(int a, int b) {
int rootA = find_root(a);
int rootB = find_root(b);
if (rootA == rootB) return;
if (size[rootA] < size[rootB]) {
parent[rootA] = rootB;
size[rootB] += size[rootA];
} else {
parent[rootB] = rootA;
size[rootA] += size[rootB];
}
count--;
}
int find_root(int node) {
while (parent[node] != node) {
parent[node] = parent[parent[node]];
node = parent[node];
}
return node;
}
bool connected(int a, int b) {
int rootA = find_root(a);
int rootB = find_root(b);
return rootA == rootB;
}
};
class Solution {
public:
bool isBipartite(vector<vector<int>>& graph) {
int size = graph.size();
UnionFind uf(size);
// 1.遍历图中每个顶点
for (int i = 0; i < size; i++) {
// 遇到孤立点,不影响二分图性质,直接跳过
if (graph[i].empty()) continue;
int v = graph[i][0];
// 2.遍历与顶点相连的所有邻接点
for (int j = 1; j < graph[i].size(); j++) {
// 若顶点与邻接点被分同一类,则不满足二分图性质
if (uf.connected(i, graph[i][j])) return false;
// 将每个邻接点聚类
uf.unite(v, graph[i][j]);
v = graph[i][j];
}
}
return true;
}
};