最近学了二分匹配,现在来整理一下。
入门题目:
poj 3692
题意:已知班级有g个女孩和b个男孩,所有女生之间都相互认识,所有男生之间也相互认识,给出m对关系表示哪个女孩与哪个男孩认识。现在要选择一些学生来组成一个团,使得里面所有人都认识,求此团最大人数。
思路:最大独立集问题:在N个点的图G中选出m个点,使这m个点两两之间没有边(没有某种关系).求m最大值.如果图G满足二分图条件,则可以用二分图匹配来做.最大独立集点数 = N - 最大匹配数。
hdu 过山车
二分匹配;说到底也就是不断查找的一个过程,利用二个独立集是否有关系来进行匹配。
不太懂的话,会去看课件。
#include <iostream>
#include <cstring>
using namespace std;
const int size=505;
bool g[size][size];
bool vis[size];
int linker[size];
int vnum,unum;
bool dfs(int u)
{
for(int v=1;v<=vnum;v++)
{
if (g[u][v]&&!vis[v])
{
vis[v]=true;
if (linker[v]==0||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
}
return false;
}
int hungry()
{
int cent(0);
memset(linker,0,sizeof(linker));
for (int u=1;u<=unum;u++)
{
memset(vis,0,sizeof(vis));
if (dfs(u))
cent++;
}
return cent;
}
int main()
{
int n,a,b;
while (cin>>n,n)
{
cin>>unum>>vnum;
int ans=0;
memset(g,0,sizeof(g));
for (int i=0;i<n;i++)
{
cin>>a>>b;
g[a][b]=1;
}
ans=hungry();
cout<<ans<<endl;
}
return 0;
}