-
1、二分图
- 什么叫二分图呢,就是不包含奇数环的图,也就是说途中可以将点分为两大类,两条边相连的两个点一定不是一类
- 通常判断二分图的方法就是染色法,每次递归到一个邻接表集合的所有点,进行反色填涂,如果出现冲突直接返回false就好
#include<iostream>
#include<cstring>
using namespace std;
const int N=2e5+10;
int color[N];
int e[N],ne[N],h[N],idx;
int n,m;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
bool dfs(int u,int c)
{
color[u]=c;
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(!color[j])
{
if(!dfs(j,3-c))return false;
}
else if(color[j]==c)return false;
}
return true;
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof h);
while(m--)
{
int a,b;
cin>>a>>b;
add(a,b),add(b,a);
}
bool flag=true;
for(int i=1;i<=n;i++)
{
if(!color[i])
{
if(!dfs(i,1))
{
flag=false;
break;
}
}
}
if(flag)puts("Yes");
else puts("No");
}
-
2、匈牙利算法
- 相亲算法,就是要是1号男生可以与1号女生和2号女生建立联系,2号男生只能与1号女生建立联系,求最大匹配对数的问题,可以先把1号女生给1号男生,到2号男生的时候,2号男生问一下1号男生能不能换一个,能换则换对数最大,换成功了就把1号女生给2号男生,不成功就老样子
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
int n1,n2,m;
int e[N],ne[N],h[N],idx;
int match[N];
bool st[N];
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
bool find(int x)
{
for(int i=h[x];~i;i=ne[i])
{
int j=e[i];
if(!st[j])
{
st[j]=true;
if(match[j]==0||find(match[j]))
{
match[j]=x;
return true;
}
}
}
return false;
}
int main()
{
cin>>n1>>n2>>m;
memset(h,-1,sizeof h);
while(m--)
{
int a,b;cin>>a>>b;
add(a,b);
}
int res=0;
for(int i=1;i<=n1;i++)
{
memset(st,false,sizeof st);
if(find(i))res++;
}
cout<<res<<endl;
return 0;
}