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 }
View Code
原文地址:https://www.cnblogs.com/idy002/p/4320663.html