作用:用于求一个二分图中的最大匹配数。
算法:一种类似手动模拟的一种暴力算法。
说明:柯尼希定理:一个二分图的最大匹配数等于这个图中最小点覆盖数,最小点覆盖数(一条边上有一点覆盖即为该边覆盖,求覆盖所有边的最小点数)。柯尼希定理的推论:最小路径覆盖=节点数-最大匹配数(最小路径覆盖—选择最少不相交的边覆盖所有的点)只使用有向无环图。
代码
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int MaxN=510;
int graph[MaxN][MaxN],flag[MaxN],nxt[MaxN];
//graph为矩阵存图
//flag标记M集合中的元素是否已有匹配点
//nxt用于储存M中的元素匹配了N中的哪个点,next好像是关键字,所以写为nxt
int N,M;
bool Find(int x)//判断找点函数
{
for(int i=1;i<=M;++i)
{
if(graph[x][i]&&!flag[i])//判断两点间是否有边寄目标点是否已有匹配
{
flag[i]=1;
if(nxt[i]==0||Find(nxt[i]))//此处递归,设计巧妙,只有在找到可行解之后再进行一下的重复赋值
{
nxt[i]=x;//储存匹配点
return true;
}
}
}
return false;
}
int match()//匹配函数
{
int sum=0;
for(int i=1;i<=N;++i)
{
memset(flag,0,sizeof(flag));//新的一轮新的匹配,标记M集合中的元素是否已有匹配点
if(Find(i))//判断点i是否可以匹配上
++sum;
}
return sum;
}
int main()
{
memset(graph,0,sizeof(graph));//初始化
memset(nxt,0,sizeof(nxt));
int T,u,v;
scanf("%d%d%d",&T,&N,&M);
while(T--)
{
scanf("%d%d",&u,&v);//存边
graph[u][v]=1;
}
int ans=match();
printf("%d
",ans);
return 0;
}