1.概念
二分图:它的顶点只可以两个集合X,Y中的一个,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。
匹配:图中的边必须一个端点在集合X中,一个端点在集合Y中,并且每个点只能使用一次。(也可能不存在边,这时匹配为0)
如果不是很理解,可以看看这个比较生动,形象
http://kukumayas.iteye.com/blog/1075610
2.匈牙利算法
匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。它是一种用增广路径求二分图最大匹配的算法。
参考其中的匈牙利算法,较为详细
http://chhaj5236.blog.163.com/blog/static/1128810812009910102617216/
3.代码
n:集合X中元素个数
m:集合Y中元素个数
a[i][j]=1:i,j之间存在一条路
b[i]:标记点i是否已经使用
c[j]:也是一种标记,如c[j]=i,则i-j这条边就属于当前的匹配。
int n,m;
int **a;
int *b,*c;
int main()
{
int i,j,ans=0;
cin>>n>>m;
a=new int*[n];
for(i=0;i<n;i++)
{
a[i]=new int[m];
}
b=new int[m];
c=new int[m];
for(i=0;i<m;i++)
{
c[i]=-1;
}
for(i=0;i<n;i++)
{
for(i=0;i<m;i++)
{
b[i]=0;
}
if(find(i))
{
ans++;
}
}
}
bool find(int i)
{
int j;
for(j=0;j<m;j++)
{
if(a[i][j]==1&&b[j]==0)
{
b[j]=1;
if(c[j]==-1||find(c[j]))//开始初始化c数组为-1。(对应下面的例子理解这一行,c[j]!=-1表示j点当前匹配中的某条边的端点,则计算find(c[j]))
{ //看与j相连的边的另一端点i是否也是其他边的端点!(有点绕,好好理解),如果也是其他边的端点,则交错路存在,否则没有
c[j]=i;
return true;
}
}
}
}
(图片转载于别的网站,忘了是什么网站)