KM模板:
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#include<stack>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 0x3f3f3f3f
#define eps 1e-8
#include<vector>
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
using namespace std;
int n,mp[333][333],cro[333];
int lx[333],ly[333],slack[333];
bool sx[333],sy[333];
bool cross(int u){
sx[u] = 1;
for(int i = 1;i <= n;++ i){
if(sy[i]) continue;
int t = lx[u] + ly[i] -mp[u][i];
if(!t){
sy[i] = 1;
if(!cro[i]||cross(cro[i])){
cro[i] = u;return true;
}
}
else
slack[i] = min(slack[i],t);
}
return false;
}
void KM(){
memset(cro,0,sizeof(cro));
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly));
for(int i = 1;i <= n;++ i){
for(int j = 1;j <= n;++ j){
lx[i] = max(lx[i],mp[i][j]);
}
}
for(int i = 1;i <= n;++ i){
memset(slack,0x3f,sizeof(slack));
while(1){
memset(sx,0,sizeof(sx));
memset(sy,0,sizeof(sy));
if(cross(i)) break;
int d = inf;
for(int j = 1;j <= n;++ j){
if(!sy[j])
d = min(d,slack[j]);
}
for(int j = 1;j <= n;++ j){
if(sx[j]) lx[j] -= d;
if(sy[j]) ly[j] += d;
else slack[j] -= d;
}
}
}
int cnt = 0;
for(int i =1;i <= n;++ i){
cnt += mp[cro[i]][i];
}
printf("%d\n",cnt);
}
int main(){
int m,i,j,k;
while(~scanf("%d",&n)){
for(i = 1;i <= n;++ i){
for(j = 1;j <= n;++ j){
scanf("%d",&mp[i][j]);
}
}
KM();
}
return 0;
}