染色法判定二分图
在学习染色判定二分图之前,要先了解二分图的一些性质;
1.二分图没有奇数环,所谓奇数环就是一个环的顶点数为奇数;
2.结合性质1,我们知道二分图染色必定是不会矛盾的,比如我们用两种颜色给二分图染色,不会出现一个顶点有两种颜色的情况;也是就说只要确定一个顶点的颜色,那么跟它相连的所有顶点颜色都确定了;
接下来就是怎么用染色法呢?其实就是dfs;
模板题:
给定一个n个点m条边的无向图,图中可能存在重边和自环。
请你判断这个图是否是二分图。
输入格式
第一行包含两个整数n和m。
接下来m行,每行包含两个整数u和v,表示点u和点v之间存在一条边。
输出格式
如果给定图是二分图,则输出“Yes”,否则输出“No”。
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
//ios::sync_with_stdio(false);
using namespace std;
const int N=100100;
const int M=100100;
const LL mod=1e9+7;
struct Node{
int to,nex;
}edge[N<<1];
int head[N];
int cnt;
void add(int p,int q){
edge[cnt].to=q;
edge[cnt].nex=head[p];
head[p]=cnt++;
}
int color[N];
bool dfs(int p,int q){//p点染成q色
color[p]=q;
for(int i=head[p];~i;i=edge[i].nex){
int v=edge[i].to;
if(!color[v]){
if(!dfs(v,3-q)) return false;
}
else if(color[v]==q) return false;
}
return true;
}
int main(){
ios::sync_with_stdio(false);
memset(head,-1,sizeof(head));
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int p,q;
cin>>p>>q;
add(p,q);
add(q,p);
}
int ok=1;
for(int i=1;i<=n;i++){
if(!color[i]){
if(!dfs(i,1)){//i点染成1
ok=0;
break;
}
}
}
if(ok) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}