Description
Input
Output
Sample Input
2 2 .m H. 5 5 HH..m ..... ..... ..... mm..H 7 8 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 0 0
Sample Output
2 10 28
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> using namespace std; #define INF 0x3f3f3f3f #define maxn 400000 struct node { int x,y; } A[105],B[105]; int n,m; char g[105][105]; int fir[maxn],nex[maxn],u[maxn],v[maxn],w[maxn],cap[maxn],flow[maxn]; int pre[maxn],vis[maxn],d[maxn],que[2*maxn]; int st,ed; int e_max; void init() { memset(flow,0,sizeof flow); memset(fir,-1,sizeof fir); e_max=0; } void add_edge(int s,int t,int c,int cus) { int e=e_max++; u[e]=s; v[e]=t; cap[e]=c; w[e]=cus; nex[e]=fir[s]; fir[s]=e; e=e_max++; u[e]=t; v[e]=s; cap[e]=0; w[e]=-cus; nex[e]=fir[t]; fir[t]=e; } bool spfa() { for(int i=0; i<=ed; i++) { vis[i]=0; d[i]=INF; pre[i]=-1; } d[st]=0; int f,r; que[f=r=0]=st; while(f<=r) { int k=que[f++]; vis[k]=0; // cout<<k<<endl; for(int i=fir[k]; ~i; i=nex[i]) { int e=v[i]; if(flow[i]<cap[i]&&d[k]+w[i]<d[e]) { pre[e]=i; d[e]=d[k]+w[i]; if(!vis[e]) { vis[e]=1; que[++r]=e; } } } } if(pre[ed]==-1) return false; return true; } int solve() { int ans=0; while(spfa()) { int sum=0; int f=pre[ed]; int minn=INF; while(f!=-1) { if(u[f]!=st&&v[f]!=ed) minn=min(minn,cap[f]-flow[f]); f=pre[u[f]]; } f=pre[ed]; while(f!=-1) { sum+=w[f]*minn; flow[f]+=minn; flow[1^f]-=minn; f=pre[u[f]]; } ans+=sum; } return ans; } void build_G() { int num1=1,num2=1; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(g[i][j]=='m') { A[num1].x=i; A[num1++].y=j; } else if(g[i][j]=='H') { B[num2].x=i; B[num2++].y=j; } } } st=0,ed=num1+num2; for(int i=1; i<num1; i++) { add_edge(st,i,1,0); add_edge(i+num1,ed,1,0); for(int j=1; j<num2; j++) add_edge(i,num1+j,1,abs(A[i].x-B[j].x)+abs(A[i].y-B[j].y)); } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { if(!n&&!m) break; for(int i=0; i<n; i++) scanf("%s",g[i]); init(); build_G(); int ans=solve(); printf("%d\n",ans); } return 0; }