题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cstdio>
using namespace std;
#define MAX 0x7fffffff
#define M 301
int lx[M],ly[M]; //记录顶点值
int Vx[M],Vy[M]; //标记访问过的点
int map[M][M],vis[M],t[M]; //t[]用于记录松弛度
int n;
int path(int x)
{
Vx[x]=1;
for(int i=1;i<=n;i++)
{
if(lx[x]+ly[i]==map[x][i]&&!Vy[i])
{
Vy[i]=1;
if(!vis[i]||path(vis[i]))
{
vis[i]=x;return 1;
}
}
if(lx[x]+ly[i]!=map[x][i]) t[i]=min(t[i],lx[x]+ly[i]-map[x][i]);
}
return 0;
}
void KM()
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
while(1)
{
memset(Vx,0,sizeof(Vx));memset(Vy,0,sizeof(Vy));
for(int i=0;i<=n;i++)t[i]=MAX;
if(path(i))break;
int p=MAX;
for(int j=1;j<=n;j++)
{
if(!Vy[j]){p=min(p,t[j]);}
}
for(int j=1;j<=n;j++)
{
if(Vx[j])lx[j]-=p;
if(Vy[j])ly[j]+=p;
else t[j]-=p;
}
}
}
int sum=0;
for(int i=1;i<=n;i++)sum+=lx[i]+ly[i];
printf("%d\n",sum);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++){scanf("%d",&map[i][j]);lx[i]=max(lx[i],map[i][j]);}
}
KM();
}
}