#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof a)
using namespace std;
const int N = 310;
int w[N][N];
int la[N], lb[N], n;
bool va[N], vb[N];
int match[N];
int slack[N];
bool dfs(int x) {
va[x] = 1;
for (int i = 1; i <= n; i++) {
if (!vb[i]) {
int t = la[x] + lb[i] - w[x][i];
if (t == 0) {
vb[i] = 1;
if (match[i] == -1 || dfs(match[i])) {
match[i] = x;
return 1;
}
}
else if(slack[i] > t)slack[i] = t;
}
}
return 0;
}
int km() {
mem(match, -1);
for (int i = 1; i <= n; i++) {
la[i] = -(1 << 30);
lb[i] = 0;
for (int j = 1; j <= n; j++) {
// la[i] = max(la[i], w[i][j]);
if (la[i] < w[i][j])la[i] = w[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
slack[j] = (1 << 30);
}
while (1) {
mem(va, 0);
mem(vb, 0);
if (dfs(i))break;
int d = (1 << 30);
for (int j = 1; j <= n; j++) {
if (!vb[j] && d > slack[j])d = slack[j];
}
for (int j = 1; j <= n; j++) {
if (va[j])la[j] -= d;
if (vb[j])lb[j] += d;
else slack[j] -= d;
}
}
}
int res = 0;
for (int i = 1; i <= n; i++) {
res += w[match[i]][i];
}
return res;
}
int main()
{
ios::sync_with_stdio(0);
while (cin >> n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> w[i][j];
}
}
cout << km() << "\n";
}
return 0;
}
KM算法 slack优化模板
猜你喜欢
转载自blog.csdn.net/weixin_43701790/article/details/104024695
今日推荐
周排行