题目链接:hdu 2255
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define inf (1e8)
int N;
int A[310][310],lx[310],ly[310],link[310],slack[310];
bool visx[310],visy[310];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
bool dfs(int x){
visx[x]=1;
for(int i=1;i<=N;i++){
if(visy[i])continue;
int t=lx[x]+ly[i]-A[x][i];
if(t==0){
visy[i]=1;
if(link[i]==-1||dfs(link[i])){
link[i]=x; return true;
}
}
else slack[i]=min(slack[i],t);
}
return false;
}
void KM(){
memset(link,-1,sizeof(link));
memset(ly,0,sizeof(ly));
for(int i=1;i<=N;i++){
lx[i]=-inf;
for(int j=1;j<=N;j++)
lx[i]=max(lx[i],A[i][j]);
}
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++)
slack[j]=inf;
while(1){
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
if(dfs(i))break;
int d=inf;
for(int j=1;j<=N;j++)
if(!visy[j])d=min(d,slack[j]);
for(int j=1;j<=N;j++)
if(visx[j])lx[j]-=d;
for(int j=1;j<=N;j++)
if(visy[j])ly[j]+=d;
else slack[j]+=d;
}
}
int tot=0;
for(int i=1;i<=N;i++)
if(link[i]!=-1)tot+=A[link[i]][i];
printf("%d\n",tot);
}
int main(){
while(scanf("%d",&N)==1){
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
A[i][j]=read();
KM();
}
return 0;
}