• 最大流增广路(KM算法) HDOJ 1533 Going Home


    题目传送门

     1 /*
     2     最小费用流:KM算法是求最大流,只要w = -w就可以了,很经典的方法
     3 */
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <cstring>
     8 using namespace std;
     9 
    10 const int MAXN = 1e2 + 10;
    11 const int INF = 0x3f3f3f3f;
    12 int x[MAXN], y[MAXN];
    13 int w[MAXN][MAXN];
    14 int visx[MAXN], visy[MAXN];
    15 int ly[MAXN];
    16 int mx[MAXN], my[MAXN];
    17 int hx[MAXN], hy[MAXN];
    18 char maze[MAXN][MAXN];
    19 int n, m, un, vn, d;
    20 
    21 bool DFS(int u) {
    22     visx[u] = true;
    23     for (int i=1; i<=un; ++i)   {
    24         if (!visy[i] && x[u] + y[i] == w[u][i]) {
    25             visy[i] = true;
    26             if (ly[i] == -1 || DFS (ly[i])) {
    27                 ly[i] = u;  return true;
    28             }
    29         }
    30         else if (x[u] + y[i] > w[u][i]) d = min (d, x[u] + y[i] - w[u][i]);
    31     }
    32     return false;
    33 }
    34 
    35 int KM(void)    {
    36     for (int i=1; i<=un; ++i)   {
    37         x[i] = -INF;
    38         for (int j=1; j<=vn; ++j)   {
    39             x[i] = max (x[i], w[i][j]);            
    40         }
    41     }
    42 
    43     memset (ly, -1, sizeof (ly));
    44     memset (y, 0, sizeof (y));
    45     for (int i=1; i<=un; ++i)    {
    46         while (true)    {
    47             memset (visx, false, sizeof (visx));
    48             memset (visy, false, sizeof (visy));
    49             d = INF;
    50             if (DFS (i))    break;
    51             for (int i=1; i<=un; ++i)   {
    52                 if (visx[i])    x[i] -= d;
    53             }
    54             for (int j=1; j<=vn; ++j)   {
    55                 if (visy[j])    y[j] += d;
    56             }
    57         }
    58     }
    59 
    60     int res = 0;
    61     for (int i=1; i<=un; ++i)   {
    62         res += x[i] + y[i];
    63     }
    64 
    65     return res;
    66 }
    67 
    68 int main(void)  {       //HDOJ 1533 Going Home
    69     //freopen ("HDOJ_1533.in", "r", stdin);
    70 
    71     while (scanf ("%d%d", &n, &m) == 2) {
    72         if (!n && !m)   break;
    73         for (int i=1; i<=n; ++i)    {
    74             scanf ("%s", maze[i] + 1);
    75         }
    76         un = vn = 0;
    77         for (int i=1; i<=n; ++i)    {
    78             for (int j=1; j<=m; ++j)    {
    79                 if (maze[i][j] == 'm')  mx[++un] = i, my[un] = j;
    80                 else if (maze[i][j] == 'H') hx[++vn] = i, hy[vn] = j;
    81             }
    82         }
    83         for (int i=1; i<=un; ++i)   {
    84             for (int j=1; j<=vn; ++j)   {
    85                 w[i][j] = -(abs (mx[i] - hx[j]) + abs (my[i] - hy[j]));
    86             }
    87         }
    88         printf ("%d
    ", -KM ());
    89     }
    90 
    91     return 0;
    92 }
    编译人生,运行世界!
  • 相关阅读:
    5种类型的程序猿
    cocos2dx 关于lua 绑定的环境配置官方文档翻译与 将自己定义c++方法绑定到lua的的方法
    智能聊天机器人实现(源代码+解析)
    storm trident merger
    分析Redis架构设计
    Spring+Struts+Hibernate 简介(转)
    java面试题(开发框架)
    Jsp+Servlet+JavaBean经典MVC模式理解
    Loadrunner中影响"响应时间"的设置
    phpredis中文手册——《redis中文手册》 php版(转)
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4662489.html
Copyright © 2020-2023  润新知