简单地说,就是一张图里的所有点可以分为两组(如上图),并且每条边都跨越两组。这样的图就是二分图。
一个图为二分图仅当:没有奇数圈;点色数为 2。
交替路(也叫交错路):从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边……形成的路径叫交替路。
增广路:从一个未匹配点出发,走交替路,以另一个未匹配点为结尾(出发的点不算),则这条交替路称为增广路
增广路定理:任意一个非最大匹配的匹配一定存在增广路。
我们可以一直找增广路,不断交换匹配。根据增广路定理,如果找不到了,就说明已经达到最大匹配。
#include <iostream>
#include <cstring>
using namespace std;
int map[100][100];
int ans=0;
int visit[100],link[100];
int n,m;
bool dfs(int x)
{
for(int i=1;i<=n;i++)
{
if(!visit[i]&&map[x][i])
{
visit[i]=1;
if(!link[i]||dfs(link[i]))
{
link[i]=x;
return 1;
}
}
}
return 0;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
map[x][y]=1;
}
for(int i=1;i<=n;i++)
{
memset(visit,0,sizeof(visit));
if(dfs(i)) ans++;
}
cout<<ans;
}