Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 20302 | Accepted: 10296 |
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 1028
题意 : m表示人,H表示房子,每个人都进入房子,一个人只能进入一个房子,问所有人都进入房子需要的路程总和最小费用是多少,走一格,表示一个单位路程
#include <stdio.h> #include <string.h> #include <cmath> #include <stdlib.h> #include <algorithm> #include <iostream> #include <queue> using std::queue; #include <vector> const int inf=0x3f3f3f3f; const int maxn=1e4; const int maxm=1e5; using namespace std; struct edge { int to,cap,cost,flow,next; }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 add_edge(int u,int v,int cap,int cost) { edge[tol].to=v; edge[tol].cap=cap; edge[tol].cost=cost; edge[tol].flow=0; edge[tol].next=head[u]; head[u]=tol++; edge[tol].to=u; edge[tol].cap=0; edge[tol].cost=-cost; edge[tol].flow=0; edge[tol].next=head[v]; head[v]=tol++; } bool spfa(int s,int t) { queue<int>q; for(int i=0;i<N;i++) { dis[N]=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].cap>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); } } } } if(pre[t]==-1) return false; else return true; } 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].cap-edge[i].flow) Min=edge[i].cap-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; } struct ac { int x, y; } dh[10050],dm[10050]; int f(ac a,ac b) { return abs(a.x-b.x)+abs(a.y-b.y); } char str[105][105]; int main() { int n,m; int M,H; while(scanf("%d%d",&n,&m)!=-1) { H=0,M=0; for(int i=0; i<n; i++) { scanf("%s",str[i]); for(int j=0; j<m; j++) { if(str[i][j]=='H') { dh[H].x=i; dh[H].y=j; H++; // cout<<99<<endl; } if(str[i][j]=='m') { dm[M].x=i; dm[M].y=j; M++; } } } init(M+H+2); for(int i=0;i<H;i++) { for(int j=0;j<M;j++) { add_edge(i+1,j+H+1,1,f(dh[i],dm[j])); //cout<<f(dh[i],dm[j])<<endl; } } for(int i=0;i<H;i++) add_edge(0,i+1,1,0); for(int i=0;i<M;i++) add_edge(i+H+1,H+M+1,1,0); int ans; int flow=mincostmaxflow(0,H+M+1,ans); cout<<ans<<endl; } return 0; }