详情看下面链接
链接:https://blog.csdn.net/wuxinxiaohuangdou/article/details/14056987
链接:https://blog.csdn.net/chenshibo17/article/details/79933191
KM模板(标注自己的理解):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
const int MAXN=305;
const int INF=0x3f3f3f3f;
int f[MAXN][MAXN];
int nx[MAXN],ny[MAXN];
bool vis_nx[MAXN],vis_ny[MAXN];
int match[MAXN];
int slack[MAXN];
int n;
bool dfs(int x)
{
vis_nx[x]=1;
for(int i=0;i<n;i++)
{
if(vis_ny[i])continue;
int gap=nx[x]+ny[i]-f[x][i];
if(gap==0)
{
vis_ny[i]=1;
if(match[i]==-1||dfs(match[i]))
{
match[i]=x;
return true;
}
}
else{
slack[i]=min(slack[i],gap);
}
}
return false;
}
int KM()
{
memset(match,-1,sizeof(match));
memset(ny,0,sizeof(ny));
int i,j,k;
for(i=0;i<n;i++)
{
nx[i]=f[i][0];
for(j=1;j<n;j++)
{
nx[i]=max(nx[i],f[i][j]);//初始化为最大值
}
}
for(i=0;i<n;i++)
{
fill(slack,slack+n,INF);//找到未匹配的和其自身最优匹配差值最小的,这样损失最小
while(1)
{
memset(vis_nx,false,sizeof(vis_nx));
memset(vis_ny,false,sizeof(vis_ny));
if(dfs(i))break;
int d=INF;
for(j=0;j<n;j++)
{
if(!vis_ny[j])d=min(d,slack[j]);
}
for(j=0;j<n;j++)
{
if(vis_nx[j])nx[j]-=d;
if(vis_ny[j])ny[j]+=d;
else slack[j]-=d;
}
}
}
int res=0;
for(i=0;i<n;i++)
{
res+=f[match[i]][i];
}
return res;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&f[i][j]);
}
}
printf("%d\n",KM());
}
return 0;
}