#include <bits/stdc++.h>
#define mset(a, x) memset(a, x, sizeof(a))
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 305;//n为容量
int n;
int mp[N][N];//往这里面存值第一个是左边编号第二个右边编号值为权值
int match[N];
int exright[N], exleft[N];
int visright[N], visleft[N];
int slack[N];
int dfs(int left) {
visleft[left] = 1;
for (int i = 0; i < n; i++) {
if (visright[i]) continue;
int tmp = exleft[left] + exright[i] - mp[left][i];
if (tmp == 0) {
visright[i] = 1;
if (match[i] == -1 || dfs(match[i])) {
match[i] = left;
return 1;
}
} else {
slack[i] = min(slack[i], tmp);
}
}
return 0;
}
int km() {
mset(match, -1); mset(exright, 0);
for (int i = 0; i < n; i++) {
exleft[i] = mp[i][0];
for (int j = 1; j < n; j++) {
exleft[i] = max(exleft[i], mp[i][j]);
}
}
for (int i = 0; i < n; i++) {
mset(slack, INF);
while (1) {
mset(visright, 0); mset(visleft, 0);
if (dfs(i)) {
break;
}
int d = INF;
for (int j = 0; j < n; j++) {
if (!visright[j]) {
d = min(d, slack[j]);
}
}
for (int j = 0; j < n; j++) {
if (visleft[j]) {
exleft[j] -= d;
}
if (visright[j]) {
exright[j] += d;
} else {
slack[j] -= d;
}
}
}
}
int res = 0;
for (int i = 0; i < n; i++) {
res += mp[match[i]][i];
}
return res;
}
int main() {
//用时往mp数组里面加值调用即可
int ans = km();//ans为答案
return 0;
}