二分图的最大匹配算法的核心在于扩展增广路,每次只有两个选择,如果当前查找的点没有匹配,那么直接匹配成功
否则我们再来看是否我们可以对这个已经匹配的点的已匹配的点的其他出边在进行匹配,使得我们当前这个新的点可以成为被匹配的点,那么
我们很容易就可以得到一条新的增广路(匹配的边),那么匹配的边数就加一,直到所有的边我们都已经扫描完毕,此时得到的已匹配的边数就是二分图的最大匹配数
其他细节我们在下面的代码中进行解析
#include"iostream"
#include"cstdio"
using namespace std;
int map[100][100];
int book[100]; //记录我们在对每个点进行扫描的时候,记录已经被我们访问到的点的
int match[100]; //记录匹配关系,最终我们的所有的匹配关系都保存在match数组里面
int n,m;
int x,y;
int dfs(int u)
{
for(int i=1;i<=n;i++) //对每一个点进行访问判断
{
if(book[i]==0&&map[u][i]==1) //如果当前的点没有被访问过,并且与其有边
{
book[i]=1; //我们将该点进行标记,以防止下一次遇到
if(match[i]==0||dfs(match[i])) //两个选择,如果没有匹配,直接匹配成功,如果已经被匹配了,我们以其被匹配的另一个点为源头再次进行增广路的判断,看看是否还可以与其他的点形成匹配,从而腾空当前的i点和u点进行匹配
{
match[i]=u;
match[u]=i;
return 1;
}
}
}
return 0;
}
int main()
{
int sum=0;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>x>>y;
map[x][y]=map[y][x]=1;
}
for(int i=1;i<=n;i++)
{
memset(book,0,sizeof(book)); //我们每次扫描完一个点我们就要重新将book数组重新清零
if(dfs(i)) //如果我们成功找到了增广路,数值加一
{
sum++;
}
}
cout<<sum<<endl;
return 0;
}