poj2195 Going Home

传送门 

C++ CE G++ AC什么鬼...

这题虽说是网络流 但是可以用之前的KM最优匹配做

会的话还是比较好写的

这里也发现了最大流/费用流更适合离散图 匈牙利/KM更适合稀疏图

 

Code:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<queue>
  6 #define ms(a,b) memset(a,b,sizeof a)
  7 #define rep(i,a,n) for(int i = a;i <= n;i++)
  8 #define per(i,n,a) for(int i = n;i >= a;i--)
  9 #define inf 2147483647
 10 using namespace std;
 11 typedef long long ll;
 12 typedef double D;
 13 #define eps 1e-8
 14 ll read() {
 15     ll as = 0,fu = 1;
 16     char c = getchar();
 17     while(c < '0' || c > '9') {
 18         if(c == '-') fu = -1;
 19         c = getchar();
 20     }
 21     while(c >= '0' && c <= '9') {
 22         as = as * 10 + c - '0';
 23         c = getchar();
 24     }
 25     return as * fu;
 26 }
 27 //head
 28 const int N = 1005;
 29 int n,m;
 30 char cmd[N];
 31 
 32 struct node {
 33     int x,y;
 34 }a[N],b[N];
 35 int top1,top2;
 36 int dis(node a,node b) {
 37     return abs(a.x-b.x) + abs(a.y-b.y);
 38 }
 39 void input() {
 40     top1 = top2 = 0;
 41     rep(i,1,n) {
 42         scanf("%s",cmd+1);
 43         rep(j,1,m) {
 44             if(cmd[j] == 'm') a[++top1] = (node){i,j};
 45             if(cmd[j] == 'H') b[++top2] = (node){i,j};
 46         }
 47     }
 48 }
 49 
 50 int v[N][N],ans;
 51 int lx[N],ly[N];
 52 int match[N];
 53 bool s[N],t[N];
 54 bool dfs(int x) {
 55     s[x] = 1;
 56     rep(y,1,n) {
 57         if(lx[x] + ly[y] == v[x][y] && !t[y]) {
 58             t[y] = 1;
 59             if(!match[y] || dfs(match[y])) {
 60                 match[y] = x;
 61                 return 1;
 62             }
 63         }
 64     }
 65     return 0;
 66 }
 67 
 68 void update() {
 69     int flw = inf;
 70     rep(x,1,n) if(s[x]) {
 71         rep(y,1,n) if(!t[y]) {
 72             flw = min(flw,lx[x] + ly[y] - v[x][y]);
 73         }
 74     }
 75     rep(i,1,n) {
 76         if(s[i]) lx[i] -= flw;
 77         if(t[i]) ly[i] += flw;
 78     }
 79 }
 80 
 81 void KM() {
 82     rep(i,1,n) {
 83         match[i] = lx[i] = ly[i] = 0;
 84         rep(j,1,n) lx[i] = max(lx[i],v[i][j]);
 85     }
 86     rep(i,1,n) {
 87         while(1) {
 88             rep(j,1,n) s[j] = t[j] = 0;
 89             if(dfs(i)) break;
 90             update();
 91         }
 92     }
 93 }
 94 
 95 int main() {
 96     while(~scanf("%d%d",&n,&m) && n && m) {
 97         input(),n = top1;
 98         rep(i,1,n) rep(j,1,n) v[i][j] = -dis(a[i],b[j]);
 99         KM(),ans = 0;
100         rep(i,1,n) ans += lx[i] + ly[i];
101         printf("%d\n",-ans);
102     }
103     return 0;
104 }

 

posted @ 2018-11-27 19:20  白怀潇  阅读(171)  评论(0编辑  收藏  举报