066.二分图判定
二分图
二分图定义
二分图的顶点集可分割为两个互不相交的子集,图中每条边依附的两个顶点都分属于这两个子集,且两个子集内的顶点不相邻。

判定 - 染色法
遍历一遍图,一边遍历一边染色,尝试用两种颜色给所有节点染色,且相邻节点的颜色都不相同
-
图不一定连通,尝试每一个未访问的起点
-
只要有一个连通分量无法二分,整个图就无法二分
模板
class Solution {
bool f=1;
int n;
void dfs(vector<vector<int>>&gra,vector<bool>&vis,vector<int>&tag,int u,int cur){
if(f==0)return;
vis[u]=1;
tag[u]=cur;
for(int v:gra[u]){
if(vis[v]==0){
dfs(gra,vis,tag,v,cur^1);
}
else{
if(tag[v]==cur){
f=0;
return;
}
}
}
}
public:
bool isBipartite(vector<vector<int>>& gra) {
this->n=gra.size();
vector<bool>vis(n,0);
vector<int>tag(n,0);
for(int i=0;f&&i<n;++i){
if(vis[i]==0){
dfs(gra,vis,tag,i,0);
}
}
return f;
}
};
练习建图
class Solution {
vector<vector<int>>gra;
vector<bool>vis;
vector<bool>tag;
bool f;
void dfs(int u,int cur){
if(f==0)return;
vis[u]=1;
tag[u]=cur;
for(int v:gra[u]){
if(vis[v]==0){
dfs(v,cur^1);
}
else{
if(tag[v]==tag[u]){
f=0;
return;
}
}
}
}
public:
bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
gra.resize(n+1);
vis.resize(n+1,0);
tag.resize(n+1,0);
f=1;
for(auto &e:dislikes){
gra[e[1]].push_back(e[0]);
gra[e[0]].push_back(e[1]);
}
for(int i=1;f&&i<=n;++i){
if(vis[i]==0){
dfs(i,0);
}
}
return f;
}
};
I am the bone of my sword

浙公网安备 33010602011771号