一、DFS 式 KM 算法
P1559 运动员最佳匹配问题
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define MAXN 25
int visL[MAXN], visR[MAXN], valueL[MAXN], valueR[MAXN];
int map[MAXN][MAXN];
int match[MAXN];
int n, d, ans;
bool KM(int u)
{
visL[u] = 1;
for (int i=1;i<=n;i++)
{
if (!visR[i])
{
if (valueL[u] + valueR[i] == map[u][i])
{
visR[i] = 1;
if (!match[i] || KM(match[i]))
{
match[i] = u;
return 1;
}
}
else d = min(d, valueL[u] + valueR[i] - map[u][i]);
}
}
return 0;
}
int main(void)
{
cin >> n;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
cin >> map[i][j];
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
int x;
cin >> x;
map[j][i] *= x;
}
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
valueL[i] = max(valueL[i], map[i][j]);
for (int i=1;i<=n;i++)
{
while (1)
{
d = 100000000;
memset(visL, 0, sizeof(visL));
memset(visR, 0, sizeof(visR));
if (KM(i)) break;
for (int j=1;j<=n;j++)
{
if (visL[j]) valueL[j] -= d;
if (visR[j]) valueR[j] += d;
}
}
}
for (int i=1;i<=n;i++)
{
ans += map[match[i]][i];
}
cout << ans;
return 0;
}
二、BFS 式 KM 算法
P6577 【模板】二分图最大权完美匹配
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
#define MAXN 503
#define INF 1e18
long long n, m, res, map[MAXN][MAXN], match[MAXN];
long long slack[MAXN], pre[MAXN], valueL[MAXN], valueR[MAXN];
bool visR[MAXN];
void KM(long long u)
{
long long x, y = 0, yy = 0, delta;
memset(pre, 0, sizeof(pre));
for(int i=1;i<=n;i++)
{
slack[i] = INF;
}
match[y] = u;
while(1)
{
x = match[y];
delta = INF;
visR[y] = 1;
for(long long i=1;i<=n;i++)
{
if(visR[i])
continue;
if(slack[i] > valueL[x] + valueR[i] - map[x][i])
{
slack[i] = valueL[x] + valueR[i] - map[x][i];
pre[i] = y;
}
if(slack[i] < delta)
{
delta = slack[i];
yy = i;
}
}
for(long long i=0;i<=n;i++)
{
if(visR[i])
{
valueL[match[i]] -= delta;
valueR[i] += delta;
}
else slack[i] -= delta;
}
y = yy;
if(match[y] == -1)
break;
}
while(y)
{
match[y] = match[pre[y]];
y = pre[y];
}
}
int main()
{
cin >> n >> m;
for(long long i=1;i<=n;i++){
for(long long j=1;j<=n;j++){
map[i][j] = -INF;
}
}
for(long long i=1;i<=m;i++)
{
long long u,v,w;
cin >> u >> v >> w;
map[u][v] = w;
}
memset(match,-1,sizeof(match));
for(long long i=1;i<=n;i++)
{
memset(visR,0,sizeof(visR));
KM(i);
}
for(long long i=1;i<=n;i++)
if(match[i] != -1)
res += map[match[i]][i];
cout << res << endl;
for(long long i=1;i<=n;i++)
{
cout << match[i] << " ";
}
return 0;
}