Going Home
题目链接
题意:在n*m的矩形上,有房子和人, 人到达房子的话费是曼哈顿距离,然后每个人走到一个房子,求最小的费用。
分析:最小费用最大流的模板
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;
typedef long long ll;
const int inf=1000000;
const int mod=1e9+7;
const int maxn=100*100+10;
const int M=100000*2+10;
struct Edge{
int to,nex,cap,flow,cost;
};
struct MFMC{
Edge edge[M];
int head[maxn],tot;
int pre[maxn],dis[maxn];
bool vis[maxn];
int N;//节点的总个数,节点编号从0~N-1;
void init(int n){
N=n;
tot=0;
memset (head,-1,sizeof (head));
}
void addedge(int u,int v,int cap,int cost){
edge[tot]=Edge{v,head[u],cap,0,cost};
head[u]=tot++;
edge[tot]=Edge{u,head[v],0,0,-cost};
head[v]=tot++;
}
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].nex){
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;
}
}mfmc;
struct node {
int x,y;
};
vector<node>house,man;
int n,m;
char mp[maxn][maxn];
int main()
{
while (scanf ("%d%d",&n,&m)!=EOF){
if (n==0&&m==0)break;
mfmc.init(maxn);
house.clear(),man.clear();
for (int i=1;i<=n;i++){
scanf ("%s",mp[i]+1);
for (int j=1;j<=m;j++){
if (mp[i][j]=='H')house.push_back(node{i,j});
else if (mp[i][j]=='m')man.push_back(node{i,j});
}
}
int s=man.size()*2+1,t=man.size()*2+2;
for (int i=0;i<man.size();i++){
mfmc.addedge(s,i,1,0);
for (int j=0;j<house.size();j++){
int dis=fabs(man[i].x-house[j].x)+fabs(man[i].y-house[j].y);
mfmc.addedge(i,man.size()+j,1,dis);
}
mfmc.addedge(man.size()+i,t,1,0);
}
int cost=0;
mfmc.minCostMaxflow(s,t,cost);
printf ("%d\n",cost);
}
return 0;
}