zoj 2404 最小费用流

时间:2021-03-26 14:31:48

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2404

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector> #define maxn 550
#define maxe 100000
#define INF 0x3f3f3f
using namespace std; struct Edge{
int from,to,cap,flow,cost;
int next;
void assign(int a,int b,int c,int d,int e,int f){
from = a; to = b; cap = c; flow = d;
cost = e; next = f;
}
}; struct MCMF{
int n,cnt;
int head[maxn];
int d[maxn];
Edge edges[maxe];
int inq[maxn];
int p[maxn];
int res[maxn]; void init(int n){
this->n = n;
cnt = ;
memset(head,-,sizeof(head));
} void addedge(int a,int b,int c,int d,int e){
edges[cnt].assign(a,b,c,d,e,head[a]);
head[a] = cnt++;
edges[cnt].assign(b,a,,,-e,head[b]);
head[b] = cnt++;
}
bool SPFA(int s,int t,int &flow,int& cost){
memset(d,0x3f,sizeof(d));
memset(inq,,sizeof(inq));
d[s] = ; inq[s] = ; p[s] = s; res[s] = INF; res[t] = ; queue<int> Q;
Q.push(s);
while(!Q.empty()){
int u = Q.front(); Q.pop();
inq[u] = ; for(int i=head[u];i!=-;i=edges[i].next){
Edge& e = edges[i];
if(e.cap > e.flow && d[e.to] > d[e.from] + e.cost){
d[e.to] = d[e.from] + e.cost;
p[e.to] = i;
res[e.to] = min(res[u],e.cap - e.flow);
if(!inq[e.to]){
Q.push(e.to); inq[e.to] = ;
}
}
}
}
if(res[t] == ) return false;
flow += res[t];
cost += d[t]*res[t];
for(int i=t;i!=s;i=edges[p[i]].from){
edges[p[i]].flow += res[t];
edges[p[i]^].flow -= res[t];
}
return true;
}
}solver;
int Mincost(int s,int t){
int flow = , cost = ;
while(solver.SPFA(s,t,flow,cost)){}
return cost;
} int main()
{
//freopen("input.txt","r",stdin);
int N,M; while(cin>>N>>M && N+M){
int ltail = ;
int rtail = ;
struct node{
int x, y;
}l[maxn],r[maxn]; char ch[];
for(int i=;i<=N;i++){
scanf("%s",ch);
for(int j=;j<M;j++){
if(ch[j] == 'H'){
r[rtail].x = i; r[rtail++].y = j;
}
else if(ch[j] == 'm'){
l[ltail].x = i; l[ltail++].y = j;
}
}
}
int n = ltail + rtail;
solver.init(n);
int s = , t = n+;
for(int i=;i<ltail;i++) solver.addedge(s,i+,,,);
for(int i=;i<rtail;i++) solver.addedge(i++ltail,t,,,);
for(int i=;i<ltail;i++)
for(int j=;j<rtail;j++){
int cost = (int)abs(1.0*l[i].x-1.0*r[j].x) + (int)abs(1.0*l[i].y-1.0*r[j].y);
solver.addedge(i+,ltail++j,,,cost);
}
printf("%d\n",Mincost(s,t));
}
}