#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
#define mem(name,value) memset(name,value,sizeof(name))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=210,maxm=110*110,inf=0x3f3f3f3f;
struct Side
{
int from,to,next,cap,flow,cost;
};
struct MCMF{
int n,top;
Side side[maxm*2];
int node[maxn],inq[maxn],d[maxn],pre[maxn],a[maxn];
void init(){
top=0; mem(node,-1);
}
void add_side(int u,int v,int cap,int cost){
side[top]=(Side){u,v,node[u],cap,0,cost};
node[u]=top++;
side[top]=(Side){v,u,node[v],0,0,-cost};
node[v]=top++;
}
bool SPFA(int s,int t,int &flow,int &cost){
//for(int i=0;i<=n;i++) d[i]=inf;
mem(d,inf);
//cout<<d[0]<<endl;
mem(inq,0);
d[s]=0; inq[s]=1; pre[s]=0; a[s]=inf;
queue<int>q;
q.push(s);
while(!q.empty()){
int u=q.front(); q.pop();
inq[u]=0;
for(int i=node[u];i!=-1;i=side[i].next){
int v=side[i].to;
if(side[i].cap>side[i].flow && d[v]>d[u]+side[i].cost){
d[v]=d[u]+side[i].cost;
pre[v]=i;
a[v]=min(a[u],side[i].cap-side[i].flow);
if(!inq[v]){ q.push(v); inq[v]=1;}
}
}
}
if(d[t]==inf) return 0;
flow+=a[t]; cost+=a[t]*d[t];
int u=t;
while(u!=s){
side[pre[u]].flow+=a[t];
side[pre[u]^1].flow-=a[t];
u=side[pre[u]].from;
}
return true;
}
int get_mincost(int s,int t){
int flow=0,cost=0;
while(SPFA(s,t,flow,cost));
return cost;
}
}mcmf;
int n,m;
char maze[maxn][maxn];
struct Node
{
int x,y;
};
vector<Node>H,M;
int main()
{
while(cin>>n>>m && n+m){
for(int i=0;i<n;i++) scanf("%s",&maze[i]);
H.clear(); M.clear();
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(maze[i][j]=='H') H.push_back((Node){i,j});
else if(maze[i][j]=='m') M.push_back((Node){i,j});
}
int nn=H.size();
mcmf.init();
for(int i=0;i<nn;i++)
for(int j=0;j<nn;j++){
int dist=abs(H[i].x-M[j].x)+abs(H[i].y-M[j].y);
mcmf.add_side(i+1,nn+j+1,1,dist);
}
for(int i=0;i<nn;i++) mcmf.add_side(0,i+1,1,0);
for(int i=0;i<nn;i++) mcmf.add_side(nn+i+1,nn+nn+1,1,0);
int ans=mcmf.get_mincost(0,nn+nn+1);
printf("%d\n",ans);
}
}
最小费用最大流模板
最新推荐文章于 2021-08-30 14:36:52 发布