HDU-2255

题目意思转化之后就是,给你一个二分图(也称
二部图)
,要求选择一些边让左边的点都对应左边的某一个点!该问题也叫做二分图最大匹配。所以可以用KM算法来做这道题。KM前提你要理解匈牙利算法最大二分匹配问题

所以先简单阐述一下KM 算法过程:定义连个点集合A,B两个集合 定义A与B之间的边为 E

(1) 初始化顶标  lx[]   ,  ly[]  两个数组; 

      ● lx[i]初始化为A集合中 i 点能到B集合某一点的最大权值,

● ly[i]
初始化0;

(2) 用匈牙利找最大匹配;

(3) 如果找到了  进行步骤(4);

否则    扩边操作,回到步骤(2);

(4) 根据匈牙利算法中的二分图连接,求出最大权值!

注释:为什么要用 lx,ly数组? KM有着贪心的思想,一开始最大匹配时都找每个点的最大权值边,不行再把要求放稍微低一点,再来进行最大匹配!所以,才需要lx,ly数组,以及扩边操作。lx 我们暂且叫做期望权值

KM算法中 在匈牙利算法那一部分加了一个条件 假设x→y ,则需要 (lx[x]+ly[y])==(value:x→y)

因为一开始lx都是最大权边,ly为0,在进行匈牙利算法之中选择时候,就只会选择指定的边,如果不能够 ,这样做的母的是筛选出边,哪一些对于左图点权值较大的边,这样第一选择一定都是自己点所能到达的最大权值。如果匹配中断了,有点无法匹配,就需要下降要求,就是将
lx 减去某个数(这个数字,是稍微降低已经匹配好的点的期望权值,稍微降低的意思就是:使得减少量尽可能最少);

如果还是不好理解,推荐这一篇博客

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cctype>
  4. #include <cmath>
  5. #include <set>
  6. #include <map>
  7. #include <list>
  8. #include <queue>
  9. #include <deque>
  10. #include <stack>
  11. #include <string>
  12. #include <vector>
  13. #include <iostream>
  14. #include <algorithm>
  15. #include <stdlib.h>
  16. #include <time.h>
  17. using namespace std;
  18. typedef long long LL;
  19. const int INF=0x3f3f3f3f;
  20. const int MOD=1e9+7;
  21. const int MAXSIZE=1e6+5;
  22. const double eps=0.0000000001;
  23. void fre()
  24. {
  25. freopen("in.txt","r",stdin);
  26. freopen("out.txt","w",stdout);
  27. }
  28. #define memst(a,b) memset(a,b,sizeof(a))
  29. #define fr(i,a,n) for(int i=a;i<n;i++)
  30.  
  31. const int MAXN=305;
  32.  
  33. int adj[MAXN][MAXN],n;
  34. int lx[MAXN],ly[MAXN],link[MAXN];
  35. bool visx[MAXN],visy[MAXN];
  36.  
  37. bool dfs(int x) // 匈牙利算法部分
  38. {
  39. visx[x]=1;
  40. for(int i=1;i<=n;i++)
  41. {
  42. if(adj[x][i]==lx[x]+ly[i]&&visy[i]==0)
  43. {
  44. visy[i]=1;
  45. if(link[i]==-1||dfs(link[i]))
  46. {
  47. link[i]=x;
  48. return true;
  49. }
  50. }
  51. }
  52. return false;
  53. }
  54.  
  55. int KM()
  56. {
  57. memset(link,-1,sizeof(link));
  58. for(int i=1;i<=n;i++)
  59. {
  60. lx[i]=-INF,ly[i]=0;
  61. for(int j=1;j<=n;j++) lx[i]=max(lx[i],adj[i][j]);
  62. }
  63. for(int k=1;k<=n;k++)//匈牙利算法
  64. {
  65. while(1)//对于每个左图的点,进行不断的查找最大权边,一旦发现有
  66. // 某一个左图点不能匹配,要求下降一点;继续
  67. {
  68. memst(visy,0);
  69. memst(visx,0);
  70. if(dfs(k)) break;
  71. int minval=INF;
  72. for(int i=1;i<=n;i++) if(visx[i]) for(int j=1;j<=n;j++) if(!visy[j]) minval=min(minval,lx[i]+ly[j]-adj[i][j]);
  73. if(minval==INF) return -1;
  74. for(int i=1;i<=n;i++) if(visx[i]) lx[i]-=minval;
  75. for(int i=1;i<=n;i++) if(visy[i]) ly[i]+=minval;
  76. }
  77. }
  78. int res=0;
  79. for(int i=1;i<=n;i++)
  80. {
  81. if(link[i]!=-1) res+=adj[link[i]][i];
  82. }
  83. return res;
  84. }
  85.  
  86. int main()
  87. {
  88. while(scanf("%d",&n)+1)
  89. {
  90. memset(adj,-1,sizeof(adj));
  91. for(int i=1;i<=n;i++)
  92. for(int j=1;j<=n;j++)
  93. scanf("%d",&adj[i][j]);
  94. printf("%d\n",KM());
  95. }
  96. return 0;
  97. }
  98.  
  99. /**************************************************/
  100. /** Copyright Notice **/
  101. /** writer: wurong **/
  102. /** school: nyist **/
  103. /** blog : http://blog.csdn.net/wr_technology **/
  104. /**************************************************/

HDU-2255(KM算法)的更多相关文章

  1. HDU 2255 KM算法 二分图最大权值匹配

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  2. hdu 3488(KM算法||最小费用最大流)

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  3. hdu 2448(KM算法+SPFA)

    Mining Station on the Sea Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  4. hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))

    Special Fish Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  5. 奔小康赚大钱 hdu 2255( KM )

    http://acm.split.hdu.edu.cn/showproblem.php?pid=2255 带权匹配问题: #include <stdio.h> #include <a ...

  6. hdu 4862 KM算法 最小K路径覆盖的模型

    http://acm.hdu.edu.cn/showproblem.php?pid=4862 选t<=k次,t条路要经过全部的点一次而且只一次. 建图是问题: 我自己最初就把n*m 个点分别放入 ...

  7. HDU 2255 & KM模板

    题意: 一张完备二分图求最优完备匹配. SOL: 这题就不讲什么sol了...毕竟是裸的KM,不会的话可以看老人家的大白鼠,一些问题看代码注释.讲讲经历(悲惨的经历) 刚打完,自信地交上去发现MLE. ...

  8. HDU 1533 KM算法(权值最小的最佳匹配)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  9. hdu 3435(KM算法最优匹配)

    A new Graph Game Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  10. hdu 1853 KM算法

    #include<stdio.h> #include<math.h> #include<string.h> #define N 200 #define inf 99 ...

随机推荐

  1. DELPHI 10.2(TOKYO) FOR LINUX的兼容性说明

    DELPHI 10.2(TOKYO) FOR LINUX的兼容性说明 自DELPHI 10.2(TOKYO) 始开始支持Linux . Delphi Linux 编译器 64 位 Linux 平台支持 ...

  2. 利用NSString的Hash方法比较字符串

    实际编程总会涉及到比较两个字符串的内容,一般会用 [string1 isEqualsToString:string2] 来比较两个字符串是否一致.对于字符串的isEqualsToString方法,需要 ...

  3. jmeter的master、slave模型启动方法

    机器A为master:机器B为slave:可以一个master挂多个slave,方法就是-R参数后面跟一个逗号分割的IP列表 slave启动命令:./jmeter-server -Djava.rmi. ...

  4. Nutch学习笔记一 ---环境搭建

    学习环境: ubuntu 概要: Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. 通过nutch,诞生了hadoop.tika ...

  5. [Algorithm] JavaScript Graph Data Structure

    A graph is a data structure comprised of a set of nodes, also known as vertices, and a set of edges. ...

  6. PS 如何制作眼泪效果

    1.用钢笔工具勾出眼泪的路径然后按Ctrl + Enter转为选区 2.按Ctrl + J 把选区复制出来,执行滤镜 > 扭曲 > 球面化 同样的方法制作流出的眼泪,然后添加图层样式选择投 ...

  7. 【POJ 3026】Borg Maze

    id=3026">[POJ 3026]Borg Maze 一个考察队搜索alien 这个考察队能够无限切割 问搜索到全部alien所须要的总步数 即求一个无向图 包括全部的点而且总权值 ...

  8. java中自带时间类使用方法实例 Date,Timestamp,DateFormat

    我们将以Java自带的时间日期类和当中的处理函数进行分析. 一.与时间日期有关的类. java.util.Date. 实现类,其对象具有时间.日期组件. java.util.Calendar. 抽象类 ...

  9. 华为P7电信4G版刷机包 EMUI2.3 官方B125 第3版 精简 ROOT

    ROM介绍 基于底包至 B125 SP03解包制作 增加自己订制的超美丽EMUI 2.3专用的全局主题 自调刷机脚本,全部权限完美百分百与官方原版相贴合. 加入Root权限并使用SuperSU 2.0 ...

  10. 怎样创建.NET Web Service http://blog.csdn.net/xiaoxiaohai123/article/details/1546941

    为什么需要Web Service 在通过internet网购买商品后,你可能对配送方式感到迷惑不解.经常的情况是因配送问题找配送公司而消耗你的大量时间,对于配送公司而言这也不是一项增值服务. 为了解决 ...