其实就是不断查询增广路,利用增广路中非匹配边比匹配边多一得性质优化匹配。
伪代码:
Function FindPath(u)
For v∈u的相邻节点
标记v已经查询过
If v未匹配 or FindPath(v的匹配的点) Then
更改u的匹配为v
Return Ture
End If
End For
Return False
For i ∈ V
清空标记
FindPath(i)
End For
C实现:
#include <cstdio>
#include <cstring>
int r[1010]={0},n,m;
bool e[5010][5010]={false},vis[1010];
bool find(int k)
{
for(int i=1;i<=n;i++) if(e[k][i]&&!vis[i]){
vis[i]=true;
if(!r[i]||find(r[i])){
r[i]=k;
return true;
}
}
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
e[u][v]=e[v][u]=true;
}
int ans=0;
for(int i=1;i<=n;i++){
memset(vis,false,sizeof(vis));
if(find(i)) ans++;
}
printf("%d\n",ans>>1);
return 0;
}