HDU-2255(KM算法)
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 减去某个数(这个数字,是稍微降低已经匹配好的点的期望权值,稍微降低的意思就是:使得减少量尽可能最少);
如果还是不好理解,推荐这一篇博客;
- #include <cstdio>
- #include <cstring>
- #include <cctype>
- #include <cmath>
- #include <set>
- #include <map>
- #include <list>
- #include <queue>
- #include <deque>
- #include <stack>
- #include <string>
- #include <vector>
- #include <iostream>
- #include <algorithm>
- #include <stdlib.h>
- #include <time.h>
- using namespace std;
- typedef long long LL;
- const int INF=0x3f3f3f3f;
- const int MOD=1e9+7;
- const int MAXSIZE=1e6+5;
- const double eps=0.0000000001;
- void fre()
- {
- freopen("in.txt","r",stdin);
- freopen("out.txt","w",stdout);
- }
- #define memst(a,b) memset(a,b,sizeof(a))
- #define fr(i,a,n) for(int i=a;i<n;i++)
- const int MAXN=305;
- int adj[MAXN][MAXN],n;
- int lx[MAXN],ly[MAXN],link[MAXN];
- bool visx[MAXN],visy[MAXN];
- bool dfs(int x) // 匈牙利算法部分
- {
- visx[x]=1;
- for(int i=1;i<=n;i++)
- {
- if(adj[x][i]==lx[x]+ly[i]&&visy[i]==0)
- {
- visy[i]=1;
- if(link[i]==-1||dfs(link[i]))
- {
- link[i]=x;
- return true;
- }
- }
- }
- return false;
- }
- int KM()
- {
- memset(link,-1,sizeof(link));
- for(int i=1;i<=n;i++)
- {
- lx[i]=-INF,ly[i]=0;
- for(int j=1;j<=n;j++) lx[i]=max(lx[i],adj[i][j]);
- }
- for(int k=1;k<=n;k++)//匈牙利算法
- {
- while(1)//对于每个左图的点,进行不断的查找最大权边,一旦发现有
- // 某一个左图点不能匹配,要求下降一点;继续
- {
- memst(visy,0);
- memst(visx,0);
- if(dfs(k)) break;
- int minval=INF;
- 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]);
- if(minval==INF) return -1;
- for(int i=1;i<=n;i++) if(visx[i]) lx[i]-=minval;
- for(int i=1;i<=n;i++) if(visy[i]) ly[i]+=minval;
- }
- }
- int res=0;
- for(int i=1;i<=n;i++)
- {
- if(link[i]!=-1) res+=adj[link[i]][i];
- }
- return res;
- }
- int main()
- {
- while(scanf("%d",&n)+1)
- {
- memset(adj,-1,sizeof(adj));
- for(int i=1;i<=n;i++)
- for(int j=1;j<=n;j++)
- scanf("%d",&adj[i][j]);
- printf("%d\n",KM());
- }
- return 0;
- }
- /**************************************************/
- /** Copyright Notice **/
- /** writer: wurong **/
- /** school: nyist **/
- /** blog : http://blog.csdn.net/wr_technology **/
- /**************************************************/
HDU-2255(KM算法)的更多相关文章
- HDU 2255 KM算法 二分图最大权值匹配
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- hdu 3488(KM算法||最小费用最大流)
Tour Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- hdu 2448(KM算法+SPFA)
Mining Station on the Sea Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))
Special Fish Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 奔小康赚大钱 hdu 2255( KM )
http://acm.split.hdu.edu.cn/showproblem.php?pid=2255 带权匹配问题: #include <stdio.h> #include <a ...
- hdu 4862 KM算法 最小K路径覆盖的模型
http://acm.hdu.edu.cn/showproblem.php?pid=4862 选t<=k次,t条路要经过全部的点一次而且只一次. 建图是问题: 我自己最初就把n*m 个点分别放入 ...
- HDU 2255 & KM模板
题意: 一张完备二分图求最优完备匹配. SOL: 这题就不讲什么sol了...毕竟是裸的KM,不会的话可以看老人家的大白鼠,一些问题看代码注释.讲讲经历(悲惨的经历) 刚打完,自信地交上去发现MLE. ...
- HDU 1533 KM算法(权值最小的最佳匹配)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- hdu 3435(KM算法最优匹配)
A new Graph Game Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 1853 KM算法
#include<stdio.h> #include<math.h> #include<string.h> #define N 200 #define inf 99 ...
随机推荐
- DELPHI 10.2(TOKYO) FOR LINUX的兼容性说明
DELPHI 10.2(TOKYO) FOR LINUX的兼容性说明 自DELPHI 10.2(TOKYO) 始开始支持Linux . Delphi Linux 编译器 64 位 Linux 平台支持 ...
- 利用NSString的Hash方法比较字符串
实际编程总会涉及到比较两个字符串的内容,一般会用 [string1 isEqualsToString:string2] 来比较两个字符串是否一致.对于字符串的isEqualsToString方法,需要 ...
- jmeter的master、slave模型启动方法
机器A为master:机器B为slave:可以一个master挂多个slave,方法就是-R参数后面跟一个逗号分割的IP列表 slave启动命令:./jmeter-server -Djava.rmi. ...
- Nutch学习笔记一 ---环境搭建
学习环境: ubuntu 概要: Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. 通过nutch,诞生了hadoop.tika ...
- [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. ...
- PS 如何制作眼泪效果
1.用钢笔工具勾出眼泪的路径然后按Ctrl + Enter转为选区 2.按Ctrl + J 把选区复制出来,执行滤镜 > 扭曲 > 球面化 同样的方法制作流出的眼泪,然后添加图层样式选择投 ...
- 【POJ 3026】Borg Maze
id=3026">[POJ 3026]Borg Maze 一个考察队搜索alien 这个考察队能够无限切割 问搜索到全部alien所须要的总步数 即求一个无向图 包括全部的点而且总权值 ...
- java中自带时间类使用方法实例 Date,Timestamp,DateFormat
我们将以Java自带的时间日期类和当中的处理函数进行分析. 一.与时间日期有关的类. java.util.Date. 实现类,其对象具有时间.日期组件. java.util.Calendar. 抽象类 ...
- 华为P7电信4G版刷机包 EMUI2.3 官方B125 第3版 精简 ROOT
ROM介绍 基于底包至 B125 SP03解包制作 增加自己订制的超美丽EMUI 2.3专用的全局主题 自调刷机脚本,全部权限完美百分百与官方原版相贴合. 加入Root权限并使用SuperSU 2.0 ...
- 怎样创建.NET Web Service http://blog.csdn.net/xiaoxiaohai123/article/details/1546941
为什么需要Web Service 在通过internet网购买商品后,你可能对配送方式感到迷惑不解.经常的情况是因配送问题找配送公司而消耗你的大量时间,对于配送公司而言这也不是一项增值服务. 为了解决 ...