使用匈牙利算法来解决二分图的最大匹配问题
Posted aininot260
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用匈牙利算法来解决二分图的最大匹配问题相关的知识,希望对你有一定的参考价值。
其实在写这个的代码的时候我是纳闷的,X集合和Y集合的点,能同时用1,或者2来表示吗?
然后我努力说服自己:它已经是二分图了
它就是存了一个 → 而已
好的我被自己说服了
二分图匹配说的就是,每个人有若干种选择,但是每种选择只能容纳一个人,问你最多能配对多少
或者说成选边的时候不能经过同一个点
最大匹配就是最多选择多少条边的问题
匈牙利算法就是,有机会就上,没机会要创造机会也要上,尽可能地给当前腾地方,腾的过程是一个递归的过程
其实这个算法挺矫情的。。
bool find(int u) { for(int tmp=g[u];tmp;tmp=e[tmp].next) if(!y[e[tmp].t]) { y[e[tmp].t]=1; if(lk[e[tmp].t]==0||find(lk[e[tmp].t])) { lk[e[tmp].t]=u; return 1; } } return 0; }
建图之后,对于每个X中的点,清空y数组之后find就好了
然后忘了说定义了,补上。。
int n,m,cnt,ans; int y[maxn],lk[maxn],g[maxn];
y记录的是Y中的下标节点是否被访问过
lk记录的是与当前下标节点(Y中)相连的X中的节点
然后给出完整实现:
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=205; 4 const int maxm=205; 5 int n,m,cnt,ans; 6 int y[maxn],lk[maxn],g[maxn]; 7 struct Edge{int t,next;}e[maxn*maxm]; 8 void addedge(int u,int v) 9 { 10 e[++cnt].t=v;e[cnt].next=g[u]; 11 g[u]=cnt; 12 } 13 bool find(int u) 14 { 15 for(int tmp=g[u];tmp;tmp=e[tmp].next) 16 if(!y[e[tmp].t]) 17 { 18 y[e[tmp].t]=1; 19 if(lk[e[tmp].t]==0||find(lk[e[tmp].t])) 20 { 21 lk[e[tmp].t]=u; 22 return 1; 23 } 24 } 25 return 0; 26 } 27 int main() 28 { 29 scanf("%d%d",&n,&m); 30 int tmp,tmp1; 31 for(int i=1;i<=n;i++) 32 { 33 scanf("%d",&tmp); 34 for(int j=1;j<=tmp;j++) 35 { 36 scanf("%d",&tmp1); 37 addedge(i,tmp1); 38 } 39 } 40 for(int i=1;i<=n;i++) 41 { 42 memset(y,0,sizeof(y)); 43 if(find(i)) ans++; 44 } 45 printf("%d",ans); 46 return 0; 47 }
老实说,这个算法,真的很神奇。。
以上是关于使用匈牙利算法来解决二分图的最大匹配问题的主要内容,如果未能解决你的问题,请参考以下文章