/*
* Author : Echo
* Email : 1666424499@qq.com
* Description :
* Created Time : 2017/9/25 16:52:26
* Last Modify : 2017/10/3 9:39:47
* File Name : MinCostMaxflow.cpp
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <time.h>
#define LL long long
#define mem(a,k) memset(a,k,sizeof(a))
const int maxint = -1u>>1;
const int maxn = 200+10;
const int maxm = 30000+100;
const int INF=1e9;
using namespace std;
struct Edge
{
int to,next,flow,cost;
void get(int a,int b,int c,int d)
{
to=a,flow=b,cost=c;next=d;
}
}edge[maxm];
int head[maxn],tol;
int pre[maxn],dis[maxn];
bool vis[maxn];
int N;
void init(int n){
N=n;
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int flow,int cost){
edge[tol].get(v,flow,cost,head[u]);head[u]=tol++;
edge[tol].get(u,0,-cost,head[v]);head[v]=tol++;
}
bool spfa(int s,int t){
queue<int>q;
for(int i=0;i<N;i++){
dis[i]=INF;
vis[i]=false;
pre[i]=-1;
}
dis[s]=0;
vis[s]=true;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=false;
for(int i= head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=true;
q.push(v);
}
}
}
}
return pre[t]!=-1;
}
int minCostMaxFlow(int s,int t,int &cost)
{
int flow=0;
cost = 0;
while(spfa(s,t)){
int Min=INF;
for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
{
if(Min >edge[i].flow)
Min=edge[i].flow;
}
for(int i=pre[t];i!=-1;i=pre[edge[i^1].to])
{
edge[i].flow-=Min;
edge[i^1].flow+=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
}
void File(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
char mp[110][110];
int men[110],topmen;
int hou[110],tophou;
int cal(int a,int b){
int x=a/1000-b/1000;
int y=a%1000-b%1000;
return abs(x)+abs(y);
}
void getmap(int n,int m){
for(int i=0;i<n;i++){
scanf("%s",mp[i]);
}
topmen=0;
tophou=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(mp[i][j]=='m'){
men[++topmen]=i*1000+j;
}
if(mp[i][j]=='H'){
hou[++tophou]=i*1000+j;
}
}
}
for(int i=1;i<=topmen;i++){
addedge(0,i,1,0);
}
for(int i=1;i<=topmen;i++){
for(int j=1;j<=tophou;j++){
addedge(i,topmen+j,1,cal(men[i],hou[j]));
}
}
for(int j=1;j<=tophou;j++){
addedge(topmen+j,2*topmen+1,1,0);
}
int cost=0;
minCostMaxFlow(0,2*topmen+1,cost);
cout<<cost<<endl;
}
int main(){
//File();
int n,m;
while(~scanf("%d%d",&n,&m)&&n||m){
init(205);
getmap(n,m);
}
return 0;
}
/*
4 5
1 2 1
2 3 1
3 4 1
1 3 2
2 4 2
4 6
1 2 1
1 3 2
2 3 1
1 4 4
2 4 1
3 4 2
6
*/
最小费用最大流minCostMaxflow 模板
最新推荐文章于 2025-04-11 16:55:30 发布