这题以前拿最小费用最大流做过,KM 直接套模板了。。。恩。。。我还需要理解。。。 #include <cstdio> #include <cstdlib> #include <iostream> #include <string.h> #include <queue> #include <math.h> #include <limits.h> #define MAX 210 using namespace std; typedef struct HOUSE{ int x,y; }HOUSE; HOUSE h[MAX],m[MAX]; int n,M; int map[MAX][MAX]; int sx[MAX],lx[MAX],ly[MAX],sy[MAX]; int match[MAX]; int HOU,MAN; bool path(int x) { int i; sx[x] = 1; for(i=1; i<MAN; i++) if( !sy[i] && lx[x] + ly[i] == map[x][i] ) { sy[i] = 1; if( match[i] == -1 || path(match[i]) ) { match[i] = x; return true; } } return false; } int KM() { int i,j,u; for( i=1; i<HOU; i++ ) { lx[i] = INT_MIN; ly[i] = 0; for(j=1; j<MAN; j++) if( lx[i] < map[i][j] ) lx[i] = map[i][j]; } memset(match,-1,sizeof(match)); for(u=1; u<HOU; u++) { while( 1 ) { memset(sx,0,sizeof(sx)); memset(sy,0,sizeof(sy)); if( path(u) ) break; int dx = INT_MAX; for(i=1; i<MAN; i++) if( sx[i] ) for(j=1; j<HOU; j++) if( !sy[j] ) dx = min( lx[i]+ly[j]-map[i][j],dx ); for(i=1; i<MAN; i++) { if( sx[i] ) lx[i] -= dx; if( sy[i] ) ly[i] += dx; } } } int sum = 0; for(i=1 ;i<HOU ;i++) if( match[i] != -1 ) sum += map[match[i]][i]; return sum; } int main() { int i,house,man,k,from,to,ans; char str[MAX]; while( scanf("%d%d",&n,&M) != EOF && n && M ) { memset(h,'/0',sizeof(h)); memset(m,'/0',sizeof(m)); memset(map,0,sizeof(map)); house = man = 1; for(i=0; i<n; i++) { scanf("%s",str); for(k=0; k<M; k++) { if( str[k] == 'H' ) { h[house].x = i; h[house++].y = k; } if( str[k] == 'm' ) { m[man].x = i; m[man++].y = k; } } } for(i=1; i<house; i++) for(k=1; k<man; k++) map[i][k] = -(abs( m[k].x - h[i].x ) + abs( m[k].y - h[i].y )); HOU = house; MAN = man; ans = KM(); printf("%d/n",-ans); } return 0; }