题目链锁: http://acm.hdu.edu.cn/showproblem.php?pid=2255
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define eps 1e-9
#define mod 1000000007
#define FOR(i,s,t) for(int i = s; i < t; ++i )
#define REP(i,s,t) for( int i = s; i <= t; ++i )
#define LL long long
#define ULL unsigned long long
#define pii pair<int,int>
#define MP make_pair
#define lson id << 1 , l , m
#define rson id << 1 | 1 , m + 1 , r
#define maxn ( 400+10 )
#define maxe ( 50000+10 )
int lx[maxn], ly[maxn], slack[maxn], w[maxn][maxn], link[maxn];
int n;
bool S[maxn], T[maxn];
bool dfs ( int u ) {
if( u < 0 ) return 1;
S[u] = 1;
for( int v= 1; v <= n; ++v ) {
if( T[v] ) continue;
int tmp = lx[u] + ly[v] - w[u][v];
if( tmp == 0 ) {
T[v] = 1;
if( link[v] == -1 || dfs( link[v] ) ) {
link[v] = u;
return 1;
}
}
else {
slack[v] = min ( slack[v], tmp );
}
}
return 0;
}
int km () {
memset( ly, 0, sizeof( ly ) );
memset( link, -1, sizeof( link ) );
for( int i = 1;i <= n; ++i ) {
lx[i] = -inf;
for( int j = 1; j <= n; ++j )
lx[i] = max( lx[i], w[i][j] );
}
for( int u = 1; u <= n; ++u ) {
memset( slack, inf, sizeof( slack ) );
while( 1 ) {
memset( T, 0, sizeof( T ) );
memset( S, 0, sizeof( S ) );
if( dfs( u ) ) break;
int d = inf;
for( int i = 1; i <= n; ++i )
if( !T[i] ) d = min ( d, slack[i] ) ;
for( int i = 1; i <= n; ++i )
if( S[i] ) lx[i] -= d;
for( int j = 1; j <= n; ++j )
if( T[j] ) ly[j] += d;
else slack[j] -= d;
}
}
int res = 0;
for( int i = 1; i <= n; ++i )
if( link[i] != -1 ) res += w[link[i]][i];
return res;
}
int main () {
while( ~scanf("%d", &n ) ) {
for( int i = 1; i <= n; ++i )
for( int j = 1; j <= n; ++j )
scanf("%d", &w[i][j] );
printf("%d\n", km() );
}
}