匈牙利算法(求最大匹配)
- 置M为空
- 找出一条增广路径p,取反得到更大的匹配M ’ 代替M
- 重复2,直到找不出增广路径
无向图模板
/*
从u开始找一个为访问的邻接点v
如果v未被匹配,则找到增广路
如果v已经匹配,则取出v的匹配顶点w,(w,v)已经被匹配,则取反,将 (w,v)改为未匹配,(u,v)设为匹配
条件是从w为起点找到新的增广路径
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000;
int n,m,pre[maxn],book[maxn],mp[maxn][maxn];
int dfs(int u)
{
for(int v=1;v<=n;v++)
{
if(!book[v]&&mp[u][v])
{
book[v]=1;
if(pre[v]==0||dfs(pre[v]))
{
pre[v]=u;
pre[u]=v;
return 1;
}
}
}
return 0;
}
int main()
{
int a,b;
scanf("%d%d",&n,&m);
memset(mp,0,sizeof(mp));
memset(pre,0,sizeof(pre));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
mp[a][b]=1;
mp[b][a]=1;
}
int cnt=0;
for(int i=1;i<=n;i++)
{
memset(book,0,sizeof(book));
if(dfs(i))
cnt++;
}
printf("%d\n",cnt);
return 0;
}
二分图的最小顶点覆盖:
定义:假如选了一个点相当于覆盖了以它为端点的所有边。最小顶点覆盖就是选最少的点来覆盖所有的边。
方法:最小顶点覆盖数=二分图最大匹配
独立集:独立集是图的一个顶点子集,如果该子集中的任何两个顶点在图中不相邻
最大独立集=总点数-最小顶点覆盖=总点数-二分图最大匹配