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; }