链接:886. 可能的二分法
题解:
class Solution {
public:
bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
// -1,代表这个点没有访问过, 0,1代表两个染色的组
std::vector<int> visited(n+1, -1);
// 构建无向图
std::unordered_map<int, std::vector<int>> graph;
for (auto& entry : dislikes) {
graph[entry[0]].push_back(entry[1]);
graph[entry[1]].push_back(entry[0]);
}
for (int i = 1; i <= n; ++i) {
// 如果这个节点已经访问过
if (visited[i] != -1) {
continue;
}
// 判断是否可以构成二分图
if (!is_split(visited, graph, i)) {
return false;
}
}
return true;
}
private:
bool is_split(std::vector<int>& visited,
std::unordered_map<int, std::vector<int>>& graph, int begin) {
std::queue<int> que;
// 将起始点入队
que.push(begin);
// 将起始点染色
visited[begin] = 0;
while (!que.empty()) {
auto f = que.front();
que.pop();
for (auto neighboard : graph[f]) {
// 如果邻居和f点相同颜色,则返回非二分图
if (visited[neighboard] >= 0
&& visited[neighboard] == visited[f]) {
return false;
}
// 已经染色过的节点,continue
if (visited[neighboard] >= 0) {
continue;
}
// 邻居取相反的颜色
visited[neighboard] = 1 - visited[f];
// 压入队列
que.push(neighboard);
}
}
return true;
}
};