标签:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 310;
int n;
int visx[maxn],visy[maxn],Lx[maxn],Ly[maxn],map[maxn][maxn];
int match[maxn];
int find(int u)
{
visx[u] = 1;
for(int v = 1; v <= n ; v++){
if(!visy[v] && Lx[u] + Ly[v] == map[u][v]){
visy[v] = 1;
if(match[v] == -1 || find(match[v])){
match[v] = u;
return 1;
}
}
}
return 0;
}
void update()
{
int a = 1 << 30;
for(int i = 1; i <= n ;i++)
if(visx[i])
for(int j = 1; j <= n ; j++)
if(!visy[j])
a = min(a,Lx[i] + Ly[j] - map[i][j]);
for(int i = 1; i <= n ;i++){
if(visx[i]) Lx[i] -= a;
if(visy[i]) Ly[i] += a;
}
}
void KM()
{
memset(match,-1,sizeof(match));
for(int i = 1 ; i <= n ; i++){
Lx[i] = Ly[i] = 0;
for(int j = 1; j <= n; j++){
Lx[i] = max(Lx[i],map[i][j]);
}
}
for(int i = 1; i <= n ;i++){
for(; ;){
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
if(find(i)) break;
else update();
}
}
}
int main()
{
while(~scanf("%d",&n)){
for(int i = 1;i <= n ;i++)
for(int j = 1; j <= n ;j++)
scanf("%d",&map[i][j]);
KM();
int res = 0;
for(int i = 1; i <= n ; i++){
if(match[i] != -1){
res += map[match[i]][i];
}
}
printf("%d\n",res);
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/zero-begin/p/4546434.html