原题连接::http://acm.hdu.edu.cn/showproblem.php?pid=2255
代码:
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 305;
const int INF = 2147483647;
int w[maxn][maxn];
int lx[maxn], ly[maxn];//顶标
int linky[maxn];
int visx[maxn],visy[maxn];
int lack , n;
bool find(int x)
{
//cout<<" Now is Finding"<<endl;
visx[x] = true;
for(int y=1 ; y<=n ; y++)
{
if(visy[y])
continue;
int t = lx[x] + ly[y] - w[x][y];
if(t == 0)
{
visy[y] = true;
if(linky[y] == -1 || find(linky[y]))
{
linky[y] = x;
return true;
}
}
else if(lack>t)
lack = t;
}
return false;
}
void KM()
{
//cout<<"调用Km!!!"<<endl;
memset(linky,-1,sizeof(linky));
memset(ly,0,sizeof(ly));
for(int x=1 ; x<=n ; x++)
{
for(;;)
{
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
lack = INF;
if(find(x))
break;
for(int i=1 ; i<=n ; i++)
{
if(visx[i])
lx[i] -= lack;
if(visy[i])
ly[i] += lack;
}
}
}
}
int main()
{
int i ,j;
while(~scanf("%d",&n))
{
int ans = 0;
memset(lx,0,sizeof(lx));
for(i=1 ; i<=n ; i++)
{
for(j=1 ; j<=n ; j++)
{
scanf("%d",&w[i][j]);
lx[i] = max(lx[i],w[i][j]);
}
}
KM();
for(i=1 ; i<=n ; i++)
ans += (lx[i]+ly[i]);
printf("%d\n",ans);
}
}