zoukankan      html  css  js  c++  java
  • KM最大匹配 HDU 2255

     KM算法详解+模板 - wenr - 博客园  http://www.cnblogs.com/wenruo/p/5264235.html

      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 #define MAXN 305
      8 #define inf 65553566
      9 int love[MAXN][MAXN];   /// 记录每个妹子和每个男生的好感度
     10 int ex_girl[MAXN];      /// 每个妹子的期望值
     11 int ex_boy[MAXN];       /// 每个男生的期望值
     12 bool vis_girl[MAXN];    /// 记录每一轮匹配匹配过的女生
     13 bool vis_boy[MAXN];     /// 记录每一轮匹配匹配过的男生
     14 int match[MAXN];        /// 记录每个男生匹配到的妹子 如果没有则为-1
     15 int slack[MAXN];        /// 记录每个汉子如果能被妹子倾心最少还需要多少期望值
     16 
     17 int n,sum;
     18 
     19 ///为女孩找匹配的男孩
     20 int find(int girl)
     21 {
     22     vis_girl[girl]=1;
     23     for(int boy=1;boy<=n;boy++)
     24     {
     25         if(vis_boy[boy]) continue;///如果男孩已经被标记过,则找下一个
     26         int gap=ex_girl[girl]+ex_boy[boy]-love[girl][boy];///看差距
     27         if(gap==0)
     28         {
     29             vis_boy[boy]=1;
     30             if(match[boy]==-1||find(match[boy]))///如果男孩未匹配过或者该男孩的妹子可以找其他人
     31             {
     32                 match[boy]=girl;///将女孩匹配给男
     33                 return 1;
     34             }
     35         }
     36         else
     37         {
     38             slack[boy]=min(slack[boy],gap);
     39         }
     40     }
     41     return 0;
     42 }
     43 void KM()
     44 {
     45     memset(match,-1,sizeof(match));
     46     memset(ex_boy,0,sizeof(ex_boy));
     47 
     48     ///每个女生的初始期望值是与他相连的男生最大的好感度
     49     for(int i=1;i<=n;i++)
     50     {
     51         ex_girl[i]=love[i][1];
     52         for(int j=2;j<=n;j++)
     53         {
     54             ex_girl[i]=max(ex_girl[i],love[i][j]);
     55         }
     56     }
     57     ///尝试为每个女孩匹配男孩
     58     for(int i=1;i<=n;i++)
     59     {
     60         fill(slack+1,slack+n+1,inf);
     61         while(1)
     62         {
     63 
     64               /// 为每个女生解决归宿问题的方法是 :如果找不到就降低期望值,直到找到为止
     65               ///记录每轮匹配中南海女孩是否被尝试匹配过
     66             memset(vis_girl,0,sizeof(vis_girl));
     67             memset(vis_boy,0,sizeof(vis_boy));
     68             if(find(i))  break;///如果发现该女孩已经找到归宿,就进行下一个女孩
     69             int d=inf;
     70             for(int j=1;j<=n;j++)
     71                 if(!vis_boy[j])///看该男孩如果没有匹配的,就将最小的期望值给他
     72                 d=min(d,slack[j]);
     73 
     74             for(int j=1;j<=n;j++)
     75             {
     76                 if(vis_girl[j])///如果女孩已经匹配,则女孩的期望值减去
     77                     ex_girl[j]-=d;
     78                 if(vis_boy[j])
     79                     ex_boy[j]+=d;
     80             }
     81         }
     82     }
     83 }
     84 int main()
     85 {
     86     while(scanf("%d",&n)!=EOF)
     87     {
     88         sum=0;
     89         for(int i=1;i<=n;i++)
     90             for(int j=1;j<=n;j++)
     91         {
     92             scanf("%d",&love[i][j]);
     93         }
     94         KM();
     95         for(int i=1;i<=n;i++)
     96         {
     97             sum+=love[match[i]][i];
     98         }
     99         printf("%d
    ",sum);
    100     }
    101 
    102 }
  • 相关阅读:
    canvas性能优化——离屏渲染
    event.target 和 event.currentTarget 的区别
    Electron 主进程和渲染进程互相通信
    谈谈 JS 垃圾回收机制
    【Vue】Vue中render函数用到的with(this)中with的用法及其优缺点
    Java递归读取文件路径下所有文件名称并保存为Txt文档
    Java读取Excel指定列的数据详细教程和注意事项
    Sybase ASE无响应的又一个情况
    AWR报告导出的过程报ORA-06550异常
    如何借助浏览器Console使用Js进行定位和操作元素
  • 原文地址:https://www.cnblogs.com/xiaotian-222/p/5459139.html
Copyright © 2011-2022 走看看