奔小康赚大钱

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 14608    Accepted Submission(s): 6358

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2255

Description:

传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子。
这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子。
另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(当然是在他们的经济范围内).现在这个问题就是村领导怎样分配房子才能使收入最大.(村民即使有钱购买一间房子但不一定能买到,要看村领导分配的).

Input:

输入数据包含多组测试用例,每组数据的第一行输入n,表示房子的数量(也是老百姓家的数量),接下来有n行,每行n个数表示第i个村名对第j间房出的价格(n<=300)。

Output:

请对每组数据输出最大的收入值,每组的输出占一行。

Sample Input:

2
100 10
15 23

Sample Output:

123

题解:

这个就是KM算法的一个模板题,说实话,我觉得KM算法设计的真的很巧妙。

可以去看看这个博客,介绍得挺好的:1.算法较为通俗理解;2.较严格证明。

然后可以将算法优化成O(n^3)的,可以参考下我的代码~

这个博客也挺好的,对于优化也有一定的阐述:https://blog.csdn.net/sixdaycoder/article/details/47720471

代码如下:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <iostream>
  5. #define mem(x) memset(x,0,sizeof(x))
  6. #define INF 0x3f3f3f
  7. using namespace std;
  8.  
  9. const int N = ;
  10. int match[N],slack[N],w[N][N],l[N],r[N],visx[N],visy[N];
  11. int n,ans;
  12.  
  13. int dfs(int x){
  14. visx[x]=;
  15. for(int i=;i<=n;i++){
  16. int tmp = l[x]+r[i]-w[x][i];
  17. if(visy[i]) continue ;
  18. if(!tmp){
  19. visy[i]=;
  20. if(!match[i] || dfs(match[i])){
  21. match[i]=x;
  22. return ;
  23. }
  24. }else slack[i]=min(slack[i],tmp);
  25. }
  26. return ;
  27. }
  28.  
  29. void KM(){
  30. for(int i=;i<=n;i++){
  31. fill(slack,slack+n+,INF);
  32. while(){
  33. mem(visx);mem(visy);
  34. if(dfs(i)) break;
  35. int d=INF;
  36. for(int i=;i<=n;i++) if(!visy[i]) d=min(d,slack[i]);
  37. for(int i=;i<=n;i++){
  38. if(visx[i]) l[i]-=d;
  39. if(visy[i]) r[i]+=d;
  40. else slack[i]-=d;
  41. }
  42. }
  43. }
  44. for(int i=;i<=n;i++){
  45. ans+=w[match[i]][i];
  46. }
  47. }
  48.  
  49. int main(){
  50. while(scanf("%d",&n)!=EOF){
  51. mem(match);mem(w);mem(l);mem(r);ans=;
  52. for(int i=;i<=n;i++){
  53. for(int j=,x;j<=n;j++){
  54. scanf("%d",&x);
  55. w[i][j]=x;
  56. l[i]=max(l[i],x);
  57. }
  58. }
  59. KM();
  60. printf("%d\n",ans);
  61. }
  62. return ;
  63. }

HDU2255:奔小康赚大钱(KM算法)的更多相关文章

  1. hdu2255 奔小康赚大钱 km算法解决最优匹配(最大权完美匹配)

    /** 题目:hdu2255 奔小康赚大钱 km算法 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:lv 思路:最优匹配(最大权完美匹配) ...

  2. hdu2255 奔小康赚大钱 KM 算法

    参见这里 #include <iostream> #include <cstring> #include <cstdio> using namespace std; ...

  3. 【HDU2255】奔小康赚大钱-KM算法

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description ...

  4. HDU - 2255 奔小康赚大钱 KM算法 模板题

    HDU - 2255 题意: 分配n所房子给n个家庭,不同家庭对一所房子所需缴纳的钱是不一样的,问你应当怎么分配房子,使得最后收到的钱最多. 思路: KM算法裸题.上模板 #include <i ...

  5. hdu 2255 奔小康赚大钱--KM算法模板

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:有N个人跟N个房子,每个人跟房子都有一定的距离,现在要让这N个人全部回到N个房子里面去,要 ...

  6. hdu 2255 奔小康赚大钱 KM算法

    看到这么奇葩的题目名我笑了,后来这么一个裸的KM调了2小时我哭了…… 这是个裸的KM算法,也没什么多说的,主要是注意多组数据时,每次都要把各种数组清空啊,赋值啊什么的,反正比较麻烦.至于为什么调了2小 ...

  7. HDU 2255 奔小康赚大钱 KM算法的简单解释

    KM算法一般用来寻找二分图的最优匹配. 步骤: 1.初始化可行标杆 2.对新加入的点用匈牙利算法进行判断 3.若无法加入新编,修改可行标杆 4.重复2.3操作直到找到相等子图的完全匹配. 各步骤简述: ...

  8. hdu-2255 奔小康赚大钱---KM模板

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2255 题目大意: Problem Description 传说在遥远的地方有一个非常富裕的村落,有一 ...

  9. hdu 2255奔小康赚大钱 KM算法模板

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=2255 一,KM算法:(借助这个题写一下个人对km的理解与km模板) KM算法主要是用来求解图的最优匹 ...

  10. HDU 2255 奔小康赚大钱 KM算法题解

    KM算法求的是完备匹配下的最大权匹配,是Hungary算法的进一步,由于Hungary算法是最大匹配的算法,不带权. 经典算法,想不出来的了,要參考别人的.然后消化吸收吧. 由于真的非常复杂的算法. ...

随机推荐

  1. PHP教程专题资源免费下载地址收藏

     PHP教程专题资源免费下载地址收藏 PHP,即Hypertext Preprocessor,是一种被广泛应用的开源通用脚本语言,尤其适用于 Web 开发并可嵌入 HTML 中去.它的语法利用了 C. ...

  2. vue---day04

    1. Node.js 1.1 介绍: - Node.js 是一个JavaScript运行环境,实质上是对Chrome V8引擎的封装. - Node.js 不是一个 JavaScript 框架,不同于 ...

  3. (数据科学学习手札11)K-means聚类法的原理简介&Python与R实现

    kmeans法(K均值法)是麦奎因提出的,这种算法的基本思想是将每一个样本分配给最靠近中心(均值)的类中,具体的算法至少包括以下三个步骤: 1.将所有的样品分成k个初始类: 2.通过欧氏距离将某个样品 ...

  4. c/c++ 结构体传参问题

    c/c++的结构体传参可以有三种方式: 1.传递结构体变量,值传递 2.传递结构体指针,地址传递 3.传递结构体成员,可是值传递也可以是地址传递 根据代码示例: 1.传递结构体变量 #include& ...

  5. P1103 书本整理

    P1103 书本整理 题目描述 Frank是一个非常喜爱整洁的人.他有一大堆书和一个书架,想要把书放在书架上.书架可以放下所有的书,所以Frank首先将书按高度顺序排列在书架上.但是Frank发现,由 ...

  6. Vue学习(五):列表渲染

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 自动化测试---mybatis的使用

    mybatis如何实现了对数据库的操作: 1.通过Resources.getResourceAsReader()或者 Resources.getResourceAsStream()加载mybatis. ...

  8. 会话描述协议(SDP)介绍

    1.SDP的引入 SDP最初用于Mbone(组播骨干网)上的多媒体会议.Mbone 是Internet 的一部分,它的主要特征是对IP组播技术的使用.IP组播技术比较适合实现多方会话. 基于组播的会议 ...

  9. C - 红与黑

    C - 红与黑 Time Limit: 1000/1000MS (C++/Others) Memory Limit: 65536/65536KB (C++/Others) Problem Descri ...

  10. CodeForces Round #521 (Div.3) D. Cutting Out

    http://codeforces.com/contest/1077/problem/D You are given an array ss consisting of nn integers. Yo ...