[学习笔记]匈牙利算法
作者:互联网
壹、模板测试链接
贰、说明
完美匹配一定是最大匹配,而最大匹配不一定是完美匹配.
交错路径:给定图G的一个匹配M,如果一条路径的边交替出现在M中和不出现在M中,我们称之为一条M-交错路径.
而如果一条M-交错路径,它的两个端点都不与M中的边关联,我们称这条路径叫做M-增广路径.
当图中再没有增广路径了,就意味着我们找到了该图的最大匹配了
二部图:给定两组顶点,但是组内的任意两个顶点间没有边相连,只有两个集合之间存在边,即组1内的点可以和组2内的点相连,这样构建出来的图就叫做二部图.
最大匹配是互相的,如果我们给X找到了最多的Y中的对应点,同样,Y中也不可能有更多的点得到匹配了
-
匈牙利算法寻找最大匹配,就是通过不断寻找原有匹配M的增广路径,因为找到一条M匹配的增广路径,就意味着一个更大的匹配M' , 其恰好比M 多一条边.
-
对于图来说,最大匹配不是唯一的,但是最大匹配的大小是唯一的.
这就是匈牙利的实现过程了.
叁、代码
using namespace Elaina;
const int maxn=500;
const int maxm=5e4;
struct edge{int to,nxt;}e[maxm+5];
int tail[maxn+5],ecnt;
int x,y,m;
inline void add_edge(const int u,const int v){
e[++ecnt]=edge{v,tail[u]};tail[u]=ecnt;
}
inline void input(){
x=readin(1),y=readin(1),m=readin(1);
int u,v;
rep(i,1,m){
u=readin(1),v=readin(1);
add_edge(u,v);
}
}
int vis[maxn+5],match[maxn+5];
int dfs(const int u){
for(int i=tail[u],v;i;i=e[i].nxt)if(!vis[v=e[i].to]){
vis[v]=1;
if(!match[v] || dfs(match[v])){
match[v]=u;
return 1;
}
}
return 0;
}
signed main(){
input();
int ans=0;
rep(i,1,x){
memset(vis+1,0,y<<2);
if(dfs(i))++ans;
}
writc(ans,'\n');
return 0;
}
标签:匹配,int,匈牙利,路径,tail,笔记,readin,算法,const 来源: https://www.cnblogs.com/Arextre/p/14371437.html