| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 18169 | Accepted: 9268 |
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
Source
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
const int maxn = 205;
const int inf = 0x3f3f3f3f;
char str[maxn];
int head[maxn], n, m; // n rows, m columns
struct Node {
int x, y;
} A[maxn], B[maxn];
int id1, id2, id, source, sink;
struct node {
int f, c, u, v, next;
} E[maxn * maxn];
bool vis[maxn];
int pre[maxn], dist[maxn];
void addEdge(int u, int v, int c, int f) {
E[id].u = u; E[id].v = v;
E[id].c = c; E[id].f = f;
E[id].next = head[u]; head[u] = id++;
E[id].u = v; E[id].v = u;
E[id].c = 0; E[id].f = -f;
E[id].next = head[v]; head[v] = id++;
}
void getMap() {
int i, j, dis; Node e;
id = id1 = id2 = 0;
for(i = 0; i < n; ++i) {
scanf("%s", str);
for(j = 0; str[j] != '\0'; ++j) {
if(str[j] == '.') continue;
e.x = i; e.y = j;
if(str[j] == 'm') A[id1++] = e;
else B[id2++] = e;
}
}
memset(head, -1, sizeof(head));
source = id1 + id2; sink = source + 1;
for(i = 0; i < id1; ++i) {
for(j = 0; j < id2; ++j) {
dis = abs(A[i].x - B[j].x) + abs(A[i].y - B[j].y);
addEdge(i, id1 + j, 1, dis); // uvcf
}
addEdge(source, i, 1, 0);
}
for(j = 0; j < id2; ++j)
addEdge(id1 + j, sink, 1, 0);
}
bool SPFA(int start, int end) {
std::queue<int> Q; int i, u, v;
memset(vis, 0, sizeof(vis));
memset(pre, -1, sizeof(pre));
memset(dist, 0x3f, sizeof(pre));
Q.push(start); vis[start] = 1; dist[start] = 0;
while(!Q.empty()) {
u = Q.front(); Q.pop();
vis[u] = 0;
for(i = head[u]; i != -1; i = E[i].next) {
v = E[i].v;
if(E[i].c && dist[v] > dist[u] + E[i].f) {
dist[v] = dist[u] + E[i].f;
pre[v] = i;
if(!vis[v]) {
Q.push(v); vis[v] = 1;
}
}
}
}
return dist[end] != inf;
}
int Min_Cost_Flow(int start, int end) {
int ans_cost = 0, u, minCut;
while(SPFA(start, end)) {
minCut = inf;
for(u = pre[end]; u != -1; u = pre[E[u].u]) {
if(minCut > E[u].c) minCut = E[u].c;
}
for(u = pre[end]; u != -1; u = pre[E[u].u]) {
E[u].c -= minCut; E[u^1].c += minCut;
}
ans_cost += minCut * dist[end];
}
return ans_cost;
}
void solve() {
printf("%d\n", Min_Cost_Flow(source, sink));
}
int main() {
// freopen("stdin.txt", "r", stdin);
while(scanf("%d%d", &n, &m), n | m) {
getMap();
solve();
}
return 0;
}#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const int maxn = 105;
const int largeNum = 210;
const int inf = 0x3f3f3f3f;
int n, m; // n rows, m columns
char str[maxn];
struct Node {
int x, y;
} A[maxn], B[maxn];
int id1, id2;
int G[maxn][maxn];
int Lx[maxn], Ly[maxn];
int match[maxn];
bool visx[maxn], visy[maxn];
int slack[maxn];
void getMap() {
int i, j, dis; Node e;
id1 = id2 = 0;
for(i = 0; i < n; ++i) {
scanf("%s", str);
for(j = 0; str[j] != '\0'; ++j) {
if(str[j] == '.') continue;
e.x = i; e.y = j;
if(str[j] == 'm') A[id1++] = e;
else B[id2++] = e;
}
}
memset(G, 0, sizeof(G));
for(i = 0; i < id1; ++i) {
for(j = 0; j < id2; ++j) {
G[i][j] = largeNum - (abs(A[i].x - B[j].x) + abs(A[i].y - B[j].y));
}
}
}
bool DFS(int cur) {
int t, y;
visx[cur] = true;
for(y = 0; y < id2; ++y) {
if(visy[y]) continue;
t = Lx[cur] + Ly[y] - G[cur][y];
if(t == 0) {
visy[y] = true;
if(match[y] == -1 || DFS(match[y])) {
match[y] = cur; return true;
}
} else if(slack[y] > t) slack[y] = t;
}
return false;
}
int KM() {
int i, j, x, d, ret;
memset(match, -1, sizeof(match));
memset(Ly, 0, sizeof(Ly));
for(i = 0; i < id1; ++i) {
Lx[i] = -inf;
for(j = 0; j < id2; ++j)
if(G[i][j] > Lx[i]) Lx[i] = G[i][j];
}
for(x = 0; x < id1; ++x) {
memset(slack, 0x3f, sizeof(slack));
while(true) {
memset(visx, 0, sizeof(visx));
memset(visy, 0, sizeof(visy));
if(DFS(x)) break;
d = inf;
for(i = 0; i < id2; ++i)
if(!visy[i] && d > slack[i])
d = slack[i];
for(i = 0; i < id1; ++i)
if(visx[i]) Lx[i] -= d;
for(i = 0; i < id2; ++i)
if(visy[i]) Ly[i] += d;
else slack[i] -= d;
}
}
ret = 0;
for(i = 0; i < id1; ++i)
if(match[i] > -1) ret += G[match[i]][i];
return ret;
}
void solve() {
printf("%d\n", largeNum * id1 - KM());
}
int main() {
// freopen("stdin.txt", "r", stdin);
while(scanf("%d%d", &n, &m), n | m) {
getMap();
solve();
}
return 0;
}POJ2195 Going Home 【最小费用流】+【二分图最佳匹配】
原文:http://blog.csdn.net/chang_mu/article/details/39995041