模板题。用输入挂。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
void cmax(int& a,int b){ if(b>a)a=b; }
void cmin(int& a,int b){ if(b<a)a=b; }
void cmax(ll& a,ll b){ if(b>a)a=b; }
void cmin(ll& a,ll b){ if(b<a)a=b; }
void add(int& a,int b,int mod){ a=(a+b)%mod; }
void add(ll& a,ll b,ll mod){ a=(a+b)%mod; }
const int oo=0x3f3f3f3f;
const int MOD=1000000007;
const int maxn=333;
int g[maxn][maxn];
int visx[maxn],visy[maxn];
int x[maxn],y[maxn];
int mat[maxn],slack[maxn];
int n;
int dfs(int u){
visx[u]=1;
for(int i=1;i<=n;i++){
if(visy[i])continue;
if(x[u]+y[i]==g[u][i]){
visy[i]=1;
if(mat[i]==-1||dfs(mat[i])){
mat[i]=u;
return 1;
}
}else cmin(slack[i],x[u]+y[i]-g[u][i]);
}
return 0;
}
void KM(){
memset(mat,-1,sizeof mat);
memset(x,0,sizeof x);
memset(y,0,sizeof y);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cmax(x[i],g[i][j]);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
slack[j]=oo;
while(1){
memset(visx,0,sizeof visx);
memset(visy,0,sizeof visy);
if(dfs(i))
break;
else{
int Min=oo;
for(int j=1;j<=n;j++)
if(!visy[j])
if(Min>slack[j])
Min=slack[j];
for(int j=1;j<=n;j++){
if(visx[j])
x[j]-=Min;
if(visy[j])
y[j]+=Min;
else
slack[j]-=Min;
}
}
}
}
}
void read(int &num)
{
char in;
bool neg=false;
while(((in=getchar()) > '9' || in<'0') && in!='-') ;
if(in=='-')
{
neg=true;
while((in=getchar()) >'9' || in<'0');
}
num=in-'0';
while(in=getchar(),in>='0'&&in<='9')
num*=10,num+=in-'0';
if(neg)
num=0-num;
}
int main(){
//freopen("E:\\read.txt","r",stdin);
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
read(g[i][j]);
KM();
int ans=0;
for(int i=1;i<=n;i++)
ans+=g[mat[i]][i];
printf("%d\n",ans);
}
return 0;
}