zoukankan      html  css  js  c++  java
  • 运动员最佳匹配问题(km算法)

    洛谷传送门

    带权二分图最大权完美匹配。

    裸的km算法。

    注意开long long。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 const long long INF = 99999999999999999;
     8 int n, match[21];
     9 long long p[21][21], q[21][21], love[21][21], ex_boy[21], ex_girl[21], slack[21];
    10 bool vis_boy[21], vis_girl[21];
    11 
    12 bool find(int i)
    13 {
    14     int j;
    15     long long gap;
    16     vis_girl[i] = 1;
    17     for(j = 1; j <= n; j++)
    18     {
    19         if(vis_boy[j]) continue;
    20         gap = ex_girl[i] + ex_boy[j] - love[i][j];
    21         if(gap == 0)
    22         {
    23             vis_boy[j] = 1;
    24             if(match[j] == -1 || find(match[j]))
    25             {
    26                 match[j] = i;
    27                 return 1;
    28             }
    29         }
    30         else slack[j] = min(slack[j], gap);
    31     }
    32     return 0;
    33 }
    34 
    35 long long KM()
    36 {
    37     int i, j;
    38     long long d, ret = 0;
    39     memset(match, -1, sizeof(match));
    40     for(i = 1; i <= n; i++)
    41      for(j = 1; j <= n; j++)
    42       ex_girl[i] = max(ex_girl[i], love[i][j]);
    43     for(i = 1; i <= n; i++)
    44     {
    45         for(j = 1; j <= n; j++) slack[j] = INF;
    46         while(1)
    47         {
    48             memset(vis_boy, 0, sizeof(vis_boy));
    49             memset(vis_girl, 0, sizeof(vis_girl));
    50             if(find(i)) break;
    51             d = INF;
    52             for(j = 1; j <= n; j++)
    53              if(!vis_boy[j])
    54               d = min(d, slack[j]);
    55             for(j = 1; j <= n; j++)
    56             {
    57                 if(vis_boy[j]) ex_boy[j] += d;
    58                 if(vis_girl[j]) ex_girl[j] -= d;
    59             }
    60         }
    61     }
    62     for(i = 1; i <= n; i++) ret += love[match[i]][i];
    63     return ret;
    64 }
    65 
    66 int main()
    67 {
    68     int i, j;
    69     scanf("%d", &n);
    70     for(i = 1; i <= n; i++)
    71      for(j = 1; j <= n; j++)
    72       scanf("%lld", &p[i][j]);
    73     for(i = 1; i <= n; i++)
    74      for(j = 1; j <= n; j++)
    75       scanf("%lld", &q[i][j]);
    76     for(i = 1; i <= n; i++)
    77      for(j = 1; j <= n; j++)
    78       love[i][j] = p[i][j] * q[j][i];
    79     printf("%lld", KM());
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    spring异常处理器
    热部署环境下,dubbo序列化的bug和优化
    函数式编程的一些魅力
    常用的jvm命令
    JS直接访问WebService(来自于网络)
    AjaxControlToolkit使用报错
    Server Application Unavailable
    ScriptManager调用WebService注意事项
    SNK签名文件添加
    vs无法调试,启动后类似于ctrl+F5
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6703898.html
Copyright © 2011-2022 走看看