hdu 1533 KM或费用流
以前用KM写过,现在再用费用流写。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <vector> 6 #include <utility> 7 #define abs(a) ((a)<0?-(a):(a)) 8 #define maxn 210 9 #define oo 0x3f3f3f3f 10 using namespace std; 11 12 struct Edge { 13 int u, v, c, f; 14 Edge( int u, int v, int c, int f ):u(u),v(v),c(c),f(f){} 15 }; 16 struct Mcmf { 17 int n, src, dst; 18 vector<Edge> edge; 19 vector<int> g[maxn]; 20 int dis[maxn], pth[maxn], ext[maxn]; 21 22 void init( int n, int src, int dst ) { 23 this->n = n; 24 this->src = src; 25 this->dst = dst; 26 for( int i=1; i<=n; i++ ) 27 g[i].clear(); 28 edge.clear(); 29 } 30 void add_edge( int u, int v, int c, int f ) { 31 g[u].push_back( edge.size() ); 32 edge.push_back( Edge(u,v,c,f) ); 33 g[v].push_back( edge.size() ); 34 edge.push_back( Edge(v,u,-c,0) ); 35 } 36 bool spfa( int &flow, int &cost ) { 37 queue<int> qu; 38 memset( dis, 0x3f, sizeof(dis) ); 39 qu.push( src ); 40 ext[src] = true; 41 dis[src] = 0; 42 pth[src] = -1; 43 while( !qu.empty() ) { 44 int u=qu.front(); 45 qu.pop(); 46 ext[u] = false; 47 for( int t=0; t<g[u].size(); t++ ) { 48 Edge &e = edge[g[u][t]]; 49 if( e.f && dis[e.v]>dis[e.u]+e.c ) { 50 dis[e.v] = dis[e.u]+e.c; 51 pth[e.v] = g[u][t]; 52 if( !ext[e.v] ) { 53 ext[e.v] = true; 54 qu.push( e.v ); 55 } 56 } 57 } 58 } 59 if( dis[dst]==oo ) return false; 60 int flw = oo; 61 for( int eid=pth[dst]; eid!=-1; eid=pth[edge[eid].u] ) 62 flw = min( flw, edge[eid].f ); 63 for( int eid=pth[dst]; eid!=-1; eid=pth[edge[eid].u] ) { 64 edge[eid].f -= flw; 65 edge[eid^1].f += flw; 66 } 67 flow += flw; 68 cost += flw*dis[dst]; 69 return true; 70 } 71 void mcmf( int &flow, int &cost ) { 72 flow = cost = 0; 73 while( spfa(flow,cost) ); 74 } 75 }; 76 77 int n, m; 78 int aa[maxn][2], bb[maxn][2], ta, tb; 79 Mcmf M; 80 81 int main() { 82 ios::sync_with_stdio( false ); 83 while(1) { 84 cin>>n>>m; 85 if( n==0 && m==0 ) return 0; 86 ta = tb = 0; 87 for( int i=1; i<=n; i++ ) 88 for( int j=1; j<=m; j++ ) { 89 char ch; 90 cin>>ch; 91 if( ch=='m' ) { 92 ta++; 93 aa[ta][0] = i; 94 aa[ta][1] = j; 95 } else if( ch=='H' ) { 96 tb++; 97 bb[tb][0] = i; 98 bb[tb][1] = j; 99 } 100 } 101 M.init( ta+tb+2, ta+tb+1, ta+tb+2 ); 102 for( int i=1; i<=ta; i++ ) 103 M.add_edge( M.src, i, 0, 1 ); 104 for( int j=ta+1; j<=ta+tb; j++ ) 105 M.add_edge( j, M.dst, 0, 1 ); 106 for( int i=1; i<=ta; i++ ) 107 for( int j=ta+1; j<=ta+tb; j++ ) { 108 int dis = abs(aa[i][0]-bb[j-ta][0])+abs(aa[i][1]-bb[j-ta][1]); 109 M.add_edge( i, j, dis, 1 ); 110 } 111 int flow, cost; 112 M.mcmf( flow, cost ); 113 cout<<cost<<endl; 114 } 115 }