HDU 1533 Going Home

来源:互联网 发布:清空文件夹内容 linux 编辑:程序博客网 时间:2024/06/04 23:28

7月冒泡第三题。

#include <iostream>#include <cstdlib>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <algorithm>#include <map>using namespace std;const int maxn = 310;const int INF = 0x3f3f3f3f;int n, m;int W[maxn][maxn];int Lx[maxn], Ly[maxn];int Left[maxn];bool S[maxn], T[maxn];bool match(int i){S[i] = 1;for(int j = 1; j <= n; j++) if(Lx[i]+Ly[j] == W[i][j] && !T[j]){T[j] = 1;if(!Left[j] || match(Left[j])){Left[j] = i;return 1;}}return 0;}void update(){int a = INF;for(int i = 1; i <= n; i++) if(S[i])for(int j = 1; j <= n; j++) if(!T[j])a = min(a, Lx[i]+Ly[j]-W[i][j]);for(int i = 1; i <= n; i++){if(S[i]) Lx[i] -= a;if(T[i]) Ly[i] += a;}}void KM(){for(int i = 1; i <= n; i++){Left[i] = Lx[i] = Ly[i] = 0;for(int j = 1; j <= n; j++)Lx[i] = max(Lx[i], W[i][j]);}for(int i = 1; i <= n; i++){for(;;){for(int j = 1; j <= n; j++) S[j] = T[j] = 0;if(match(i)) break; else update();}}}inline void readint(int &x){char c;c = getchar();while(!isdigit(c)) c = getchar();x = 0;while(isdigit(c)) x = x*10+c-'0', c = getchar();}inline void writeint(int x){if(x > 9) writeint(x/10);putchar(x%10+'0');}struct node{int x, y;node(int x=0, int y=0): x(x), y(y) {}}H[maxn], M[maxn];int hh, mm;char s[110][110];void read_case(){for(int i = 0; i < n; i++) scanf("%s", s[i]);}int Dist(node a, node b) { return abs(a.x-b.x) + abs(a.y-b.y); }void build(){hh = mm = 1;for(int i = 0; i < n; i++)for(int j = 0; j < m; j++){if(s[i][j] == 'm'){M[mm++] = node(i, j);}if(s[i][j] == 'H'){H[hh++] = node(i, j); }}mm--, hh--;n = hh, m = mm;for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){W[i][j] = -(Dist(H[i], M[j]));}}}void solve(){read_case();build();KM();int ans = 0;for(int i = 1; i <= n; i++) ans += W[Left[i]][i];writeint(-ans), puts("");}int main(){readint(n), readint(m);for(; (n || m); readint(n), readint(m)){solve();}return 0;}


原创粉丝点击