什么是二分图?二分图就是所有的点可以呗分为俩个集合,且集合内部的点互相之间没有边。
如果有一棵树,如果这颗树里面没有奇数环,那么这颗树就可以被划分为一个二分图。如何判断一颗树是否为一个二分图,一般会用到染色法。
染色法即通过dfs的方式,将一个点染色为1或则2,然而1所连接的边必须式2,不能是1,同理,2能连接的边也必须是1。代码如下
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
const int N=3e5+10;
int e[N],ne[N],idx;
int h[N];
int co[N];
void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
bool dfs(int u,int x){//判断是否能染色成功
co[u]=x;//将u染成x
for(int i=h[u];i!=-1;i=ne[i]){
int v=e[i];
if(co[v]){//如果v的颜色确定
if(co[v]==x)return false;//如果v,u的颜色相同,不能成功
}
else {//v的颜色未确定
if(!dfs(v,3-x))return false;//判断v 染成3-x是否成功,如果失败返回false
}
}
return true;
}
int main(){
cin>>n>>m;
memset(h,-1,sizeof h);
for(int i=1;i<=m;i++){//存边
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
for(int i=1;i<=n;i++){
if(!co[i]){//考虑到存可能在不相连的
if(dfs(i,1))continue;
else {cout<<"No\n";return 0;}
}
}
cout<<"Yes\n";
return 0;
}
那么匈牙利算法又和这个二分有什么关系捏?
匈牙利算法,又称km算法,时间复杂度未n^3,匈牙利的算法是可以解决二分图的最大完美匹配的问题。就比如有俩个集合,一边是男的一边是女的,男的有n1个,女的有n2个,如果双发之间有好感度就有可能在一起,当然假设男女的性取向都很正确,所以不存在男男,女女的情况,而我们要求的就是男女能匹配到一起的最大匹配数量。
那么我们该如何实现捏?这里的话假设我们从男方角度出发,如果男有与女生有好感度,那么我们就可以记录女生所匹配的,如果这个女生已经有匹配的了,那么我们试试嫩否让这个女生匹配的男的换一个女朋友然后再占为己有。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
typedef double D;
const int N =1e6+10;
typedef pair<int,int>Pii;
LL a[N];
int e[N],h[N],ne[N],idx;
int st[510];
int match[N];
void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
bool dfs(int u){
for(int i=h[u];i!=-1;i=ne[i]){
int v=e[i];//预选的人之一
if(st[v])continue;
st[v]=1;//表示这个已经尝试匹配过了,不用再尝试
if(!match[v]||dfs(match[v])){//如果这个人没有匹配成功,或者她的匹配对象还能再找一个,那么就可以匹配成
match[v]=u;
return true;
}
}
return false;//如果所有预选的对象都不能成功,那么就返回false
}
void solved(){
int n,m,e;
cin>>n>>m>>e;
memset(h,-1,sizeof h);
for(int i=1;i<=n;i++){
int a,b;
cin>>a>>b;
add(a,b);//单向边
}
int ans=0;
for(int i=1;i<=n;i++){
if(dfs(i))ans++;//匹配成功,答案加1
memset(st,0,sizeof st);//清空数组
}
cout<<ans<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int tt;
tt=1;
while(tt--){
solved();
}
}
完结撒花!!!