图着色问题的判别
根据目前所做的题目,图着色问题有一个显著的特点,就是将图中的节点分成几组。
解决思路
对图深度优先遍历(或广度优先遍历)的过程中,进行节点着色。不同的题有不同的着色策略,这里不再详述。大致可根据分成的组的数目,设置颜色的数量。
- 根据输入信息,生成邻接矩阵。
- 深度优先遍历邻接矩阵,并着色。
例题
Leetcode 785.判断二分图
class Solution {
public:
bool dfs(const vector<vector<int>>& grid, vector<int>& color, int index, int colored, int N)
{
color[index] = colored;
int colorNeigh = (colored == 1 ? 2 : 1);
for(int j = 0; j < N; j++) {
if(grid[index][j] == 1) {
if(color[j] == colored) return false;
if(color[j] == 0 && !dfs(grid, color, j, colorNeigh, N)) return false;
}
}
return true;
}
bool isBipartite(vector<vector<int>>& graph) {
int N = graph.size();
vector<int> color(N, 0);
vector<vector<int>> grid(N, vector<int>(N,0));
for(int i = 0; i < N; i++) {
for(int j = 0; j < graph[i].size(); j++) {
grid[i][graph[i][j]] = 1;
}
}
for(int i = 0; i < N; i++) {
if(color[i] == 0) {
if(!dfs(grid, color, i, 1, N)) {
return false;
}
}
}
return true;
}
};
Leetcode 886.可能的二分法
class Solution {
public:
bool dfs(const vector<vector<int>>& grid, vector<int>& color, int index, int colored, int N)
{
color[index] = colored;
int colorNeigh = (colored == 1 ? 2 : 1);
for(int j = 0; j < N; j++) {
if(grid[index][j] == 1) {
if(color[j] == colored) return false;
if(color[j] == 0 && !dfs(grid, color, j, colorNeigh, N)) return false;
}
}
return true;
}
bool isBipartite(vector<vector<int>>& graph) {
int N = graph.size();
vector<int> color(N, 0);
vector<vector<int>> grid(N, vector<int>(N,0));
for(int i = 0; i < N; i++) {
for(int j = 0; j < graph[i].size(); j++) {
grid[i][graph[i][j]] = 1;
grid[graph[i][j]][i] = 1;
}
}
for(int i = 0; i < N; i++) {
if(color[i] == 0) {
if(!dfs(grid, color, i, 1, N)) {
return false;
}
}
}
return true;
}
};