染色法判断二分图
染色法原理:
首先任意取出一个顶点进行染色,和该节点相邻的点有三种情况:
-
如果未染色,那么继续染色此节点(染为另一种颜色)
-
如果已染色但和当前节点颜色不同,则跳过该点
-
如果已染色并且和当前节点颜色相同,返回失败(该图不是二分图)
明确二分图、奇数环、染色法之间的关系:
-
如果一个图中存在奇数环,那么这个图一定不是二分图;这一点显然成立。
-
如果一个图中不存在奇数环,那么这个图一定是二分图:
证明略
模板:
#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std;
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define ll long long
#define pb push_back
inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void write(int x){if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10+'0');}
int n,m,a,b;
std::vector<int> v[100010];
int vis[100010];
bool dfs(int u,int c){
vis[u]=c;
for(int i:v[u]){
if(!vis[i]){
if(!dfs(i,3-c)) return false;//若是1,染色为2,若是2,染色为1
}
else if(vis[i]==c) return false;
}
return true;
}
int main(){
n=read(),m=read();
rep(i,1,m){
cin>>a>>b;
v[a].pb(b);
v[b].pb(a);
}
bool f=true;
rep(i,1,n){//没有染过色,就染色为1
if(!vis[i]){
if(!dfs(i,1)){
f=false;
break;
}
}
}
if(f) puts("Yes");
else puts("No");
return 0;
}
求二分图的最大匹配(匈牙利算法)
求二分图最大匹配数量
#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std;
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define ll long long
#define pb push_back
inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void write(int x){if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10+'0');}
int n1,n2,m;
std::vector<int> v[510];
bool st[100010];//匹配状态
int match[100010];//记录i女生匹配了哪一个男生
bool find(int x){
for(int i:v[x]){
if(!st[i]){
st[i]=true;
if(!match[i]||find(match[i])){//没有匹配或者匹配的男生能够寻找到其他的女生
match[i]=x;
return true;
}
}
}
return false;
}
int main(){
n1=read(),n2=read(),m=read();
int a,b;
while(m--){
a=read(),b=read();
v[a].pb(b);
}
int res=0;
rep(i,1,n1){
memset(st,false,sizeof st);//每次都将所有女生更新为未被更新的状态
if(find(i))
res++;
}
write(res);
return 0;
}