匈牙利算法是用来求二分图匹配的算法,一般有bfs和dfs两种实现,我一般都是写的dfs的实现,感觉这个比较好理解,实现也比较简单。
二部图:若一个图的顶点可以划分到2个集合,使得每个集合内的顶点之间没有连边,那么这个图就叫做二分图或二部图。
二分匹配问题:求最大边无关集。
交替链:二分图的一条路径,路径的起点和终点来自于不同的集合,且均未被标记(未匹配),且路径中的相邻结点来自不同的集合。
匈牙利算法:存在交替链<=>存在更优匹配
为什么在maxmatch中只需对每个结点一次求一次交替链即可?
答:因为每求一次交替链后,可能增加匹配成功的结点,上一次匹配成功的结点不会变(匹配方式可能变了),而交替链是否存在与匹配成功的结点有关,所以若第一次求从某个点出发不存在交替链,则以后求也不会存在交替链,所以扫描一遍即可。
参考代码:
int x[N],y[N],vis[N];
//求是否存在交替链
int path(int u)
{
int v;
for(v=0;v<n;v++) if(g[u][v] && vis[v]==0)
{
vis[v]=1;
if(y[v]==-1 || path(v))
{
x[u]=v;
y[v]=u;
return 1;
}
}
return 0;
}
//求最大匹配数
int maxmatch()
{
int max=0,u;
memset(x,0xff,sizeof(x));
memset(y,0xff,sizeof(y));
for(u=0;u<n;u++)
{
memset(vis,0,sizeof(vis));
max+=path(u);
}
}