zoukankan      html  css  js  c++  java
  • hdu 2255 奔小康赚大钱 (km算法模板)

    题目链接:

      http://acm.hdu.edu.cn/showproblem.php?pid=2255

    解题思路:

      了解km算法以后,就可以直接套用km算法,km算法:完备匹配下的最大权匹配,

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 #define maxn 310
     8 #define INF 0x3f3f3f3f
     9 int map[maxn][maxn], used[maxn], s[maxn], n, m;
    10 int lx[maxn], ly[maxn], visx[maxn], visy[maxn];
    11 
    12 int find (int x)
    13 {//匈牙利算法,增广路
    14     visx[x] = 1;
    15     for (int i=1; i<=n; i++)
    16     {
    17         if (!visy[i] && lx[x] + ly[i] == map[x][i])
    18         {
    19             visy[i] = 1;
    20             if (!used[i] || find(used[i]))
    21             {
    22                 used[i] = x;
    23                 return 1;
    24             }
    25         }
    26         else
    27             s[i] = min (s[i], lx[x]+ly[i]-map[x][i]);
    28     }
    29     return 0;
    30 }
    31 
    32 int KM ()
    33 {
    34     memset (lx, 0, sizeof(lx));
    35     memset (ly, 0, sizeof(ly));
    36     memset (used, 0, sizeof(used));
    37     for (int i=1; i<=n; i++)
    38         for (int j=1; j<=n; j++)
    39             lx[i] = max (lx[i], map[i][j]);
    40     for (int i=1; i<=n; i++)
    41     {
    42         for (int j=1; j<=n; j++)
    43             s[j] = INF;
    44 
    45         while (1)
    46         {
    47             memset (visx, 0, sizeof(visx));
    48             memset (visy, 0, sizeof(visy));
    49 
    50             if (find (i))
    51                 break;
    52             int num = INF;
    53             for (int j=1; j<=n; j++)
    54                 if (!visy[j])
    55                     num = min (num, s[j]);
    56             for (int j=1; j<=n; j++)
    57             {
    58                 if (visx[j])
    59                     lx[j] -= num;
    60                 if (visy[j])
    61                     ly[j] += num;
    62                 else
    63                     s[j] -= num;
    64             }
    65         }
    66     }
    67     int res = 0;
    68     for (int j=1; j<=n; j++)
    69         res += map[used[j]][j];
    70     return res;
    71 }
    72 int main ()
    73 {
    74     while (scanf ("%d", &n) != EOF)
    75     {
    76         for (int i=1; i<=n; i++)
    77             for (int j=1; j<=n; j++)
    78                 scanf ("%d", &map[i][j]);
    79         printf ("%d
    ", KM());
    80     }
    81     return 0;
    82 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Linux下让一个程序开机自动启动
    Heartbeat高可用解决方案
    NFS文件共享
    清除系统日志的三个脚本
    nfs+rsync+inotify实现文件的实时同步
    安装配置rsync服务端
    shell中如何进行算术运算
    linux下查看账号密码的过期时间和设置时间
    配置Nginx作为web server详解
    [LeetCode] 398. Random Pick Index ☆☆☆
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4479182.html
Copyright © 2011-2022 走看看