#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf -0x3f3f3f3f
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
const int maxn=11000;
struct Edge{
int from,to,cap,flow,cost;
Edge(int u,int v,int c,int f,int w):from(u),to(v),cap(c),flow(f),cost(w) {}
};
struct MCMF{
int n,m,s,t;
vector<Edge>edges;
vector<int>G[maxn];
int inq[maxn];
int d[maxn];
int p[maxn];
int a[maxn];
void init(int n){
this->n=n;
for(int i=0;i<=n;i++)
G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap,int cost){
edges.push_back(Edge(from,to,cap,0,cost));
edges.push_back(Edge(to,from,0,0,-cost));
m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool spfa(int s,int t,int &flow,int& cost){
for(int i=0;i<=n;i++)
d[i]=INF;
mem0(inq);
d[s]=0;
inq[s]=1;
p[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=0;i<G[u].size();i++){
Edge& e=edges[G[u][i]];
if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){
d[e.to]=d[u]+e.cost;
p[e.to]=G[u][i];
a[e.to]=min(a[u],e.cap-e.flow);
if(!inq[e.to]){
Q.push(e.to);
inq[e.to]=1;
}
}
}
}
if(d[t]==INF)
return false;
flow+=a[t];
cost+=d[t]*a[t];
int u=t;
while(u!=s){
edges[p[u]].flow+=a[t];
edges[p[u]^1].flow-=a[t];
u=edges[p[u]].from;
}
return true;
}
int Mincost(int s,int t){
int flow=0;
int cost=0;
while(spfa(s,t,flow,cost));
return cost;
}
};
MCMF ZYC;
char mp[101][101];
struct node{
int x;
int y;
}line1[maxn],line2[maxn];
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0)
break;
int num=0;
ZYC.init(maxn);
int s=0;
int t=m*n+1;
int cnt1=0,cnt2=0;
getchar();
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
for(int j=1;j<=m;j++){
//printf("%c\n",mp[i][j]);
if(mp[i][j]=='m'){
line1[cnt1].x=i;
line1[cnt1].y=j;
ZYC.AddEdge(0,(i-1)*m+j,1,0);
cnt1++;
}
if(mp[i][j]=='H'){
line2[cnt2].x=i;
line2[cnt2].y=j;
ZYC.AddEdge((i-1)*m+j,t,1,0);
cnt2++;
}
}
}
for(int i=0;i<cnt1;i++)
for(int j=0;j<cnt2;j++){
int cost=fabs(line1[i].x-line2[j].x)+fabs(line1[i].y-line2[j].y);
ZYC.AddEdge((line1[i].x-1)*m+line1[i].y,(line2[j].x-1)*m+line2[j].y,1,cost);
}
printf("%d\n",ZYC.Mincost(0,t));
}
return 0;
}
HDU 1533.Going Home(费用流模板)
最新推荐文章于 2019-10-12 19:59:01 发布
本文介绍了一种基于最小费用最大流算法的具体实现方法,并通过一个具体的实例来展示如何使用该算法解决特定的问题。该算法适用于寻找从源点到汇点的路径中,既能够达到最大流量又具有最小总成本的方案。
406

被折叠的 条评论
为什么被折叠?



