最小费用最大流,地址: http://acm.pku.edu.cn/JudgeOnline/problem?id=2195
#include <stdio.h>
const int MAX = 3276700;
const int LEN = 205;
int house[LEN][2]; int hl; int man[LEN][2]; int ml;
void init () { hl = ml = 0; }
struct { int c; int f; int weight; }map[LEN][LEN];
int nearl[LEN][LEN];
void initm ( int n ) {
for ( int i=0; i<n; i++ ) { nearl[i][0] = 1; for ( int j=0; j<n; j++ ) { map[i][j].c = map[i][j].f = map[i][j].weight = 0; } } }
void add ( int a, int b, int c, int weight ) {
if ( ! map[a][b].c && ! map[b][a].c ) { nearl[a][ nearl[a][0]++ ] = b; nearl[b][ nearl[b][0]++ ] = a; } map[a][b].c += c; map[a][b].weight += weight; }
int cost[LEN]; int road[LEN];
int ad ( int s, int t, int *mincost ) {
int p = t; int min = MAX;
while ( p != s ) { if ( min > map[ road[p] ][p].c - map[ road[p] ][p].f ) { min = map[ road[p] ][p].c - map[ road[p] ][p].f; } p = road[p]; }
p = t; while ( p != s ) { map[ road[p] ][p].f += min; map[ p ][ road[p] ].f -= min; *mincost += min * map[ road[p] ][p].weight; p = road[p]; } return min; }
int mima ( int s, int t, int n, int *mincost ) {
int maxflow = 0; *mincost = 0; do { road[t] = -1; cost[s] = 0; for ( int i=1; i<n; i++ ) { cost[i] = MAX; }
int flag = 1; while ( flag ) { flag = 0; for ( int v=0; v < n; v++ ) { for ( int u=1; u<nearl[v][0]; u++ ) { if ( map[ nearl[v][u] ][v].f < map[ nearl[v][u] ][v].c && cost[ nearl[v][u] ] < MAX ) { if ( cost[v] > cost[ nearl[v][u] ] + map[ nearl[v][u] ][v].weight ) { cost[v] = cost[ nearl[v][u] ] + map[ nearl[v][u] ][v].weight; road[v] = nearl[v][u]; flag = 1; } } } } } if ( road[t] != -1 ) { maxflow += ad ( s, t, mincost ); } }while ( road[t] != -1 );
return maxflow; }
int abs ( int a ) {
return a > 0 ? a : -a; }
int main () {
int n, m;
while ( scanf ( "%d%d", &n, &m ) != EOF && ( n || m ) ) { int i, j; char in[105];
gets ( in ); init (); for ( i=0; i<n; i++ ) { scanf ( "%s", &in ); for ( j=0; j<m; j++ ) { if ( in[j] == 'H' ) { house[hl][0] = i; house[hl][1] = j; hl ++; continue; } if ( in[j] == 'm' ) { man[ml][0] = i; man[ml][1] = j; ml ++; continue; }
} }
initm ( ml+hl+2 ); for ( i=0; i<ml; i++ ) { add ( 0, i+1, 1, 0 ); add ( +1, 0, 0, 0 ); } for ( i=0; i<ml; i++ ) { for ( j=0; j<hl; j++ ) { int weight = abs ( man[i][0]-house[j][0] ) + abs ( man[i][1]-house[j][1] ); add ( i+1, ml+1+j, 1, weight ); add ( ml+1+j, i+1, 0, -weight ); } } for ( j=0; j<hl; j++ ) { add ( ml+1+j, ml+hl+1, 1, 0 ); add ( ml+hl+1, ml+1+j, 0, 0 ); }
int mincost;
mima ( 0, ml+hl+1, ml+hl+2, &mincost );
printf ( "%d\n", mincost ); } return 0; }
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|
公告
决定从线程开始!!
常用链接
留言簿(6)
随笔档案
搜索
最新评论
阅读排行榜
评论排行榜
|
|