HDU 2255 奔小康赚大钱 KM算法的简单解释
KM算法一般用来寻找二分图的最优匹配。
步骤:
1.初始化可行标杆
2.对新加入的点用匈牙利算法进行判断
3.若无法加入新编,修改可行标杆
4.重复2.3操作直到找到相等子图的完全匹配。
各步骤简述:
1.根据二分图建立2个可行标杆;
lx为x的可行标杆,初始化lx[i]为与i点相连的最大边
ly为y的可行标杆,初始化为0.
可行性的判断条件应为lx[x]+ly[y] >= Map[x][y]。
2.对于新加入的点用匈牙利算法经行判断,确定改点能否加入旧子图中,形成新子图。
对于该加入的点有两种可能:
2.1.找到某个y点,该y点为被连接,则与该点相连,并符合条件
2.2找到某个y点,该y点已经被某x1点所连接,则对x1点经行深搜,若x1可以找到新的连接点,则修改x1的连接路径,并使x点与y点相连。
3.如果发现无法再向已有的相等子图中加入边,则证明不再有lx[x]+ly[y]==Map[x][y]成立,那么我们对x和y的可行标杆经行修改。
当找不到增广路径时,对于搜索过的路径上的XY点,设该路径上的X顶点集为S,Y顶点集为T,对所有在S中的点xi及不在T中的点yj,计算d=min{(L(xi)+L(yj)-weight(xiyj))},从S集中的X标杆中减去d,并将其加入到T集中的Y的标杆中,由于S集中的X标杆减少了,而不在T中的Y标杆不变,相当于这两个集合中的lx(x)+ly(y)变小了,也就是,lx[x]+ly[y]将变小,便有可能有lx[x]+ly[y]==Map[x][y]成立,即可能会加入新的边。
4.重复2.3过程,知道找到完备相等子图为止。
时间复杂度:优化后大概为O(n^3);
代码:
#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 1005
#define mod 1000000007 using namespace std; int visx[MAX],visy[MAX],lx[MAX],ly[MAX],linker[MAX],slack[MAX],Map[MAX][MAX],n; bool DFS(int x)
{
visx[x]=;
for(int y=;y<=n;y++)
{
if(visy[y])
continue;
int tmp=lx[x]+ly[y]-Map[x][y];
if(tmp==)
{
visy[y]=;
if(linker[y]==- || DFS(linker[y]))
{
linker[y]=x;
return true;
}
}
else
{
slack[y]=min(slack[y],tmp);
}
}
return false;
} int KM()
{
int i,j;
memset(ly,,sizeof(ly));//初始化可行标杆ly
memset(linker,-,sizeof(linker));
for(i=; i<=n; i++)//初始化可行标杆lx
{
lx[i]=-INF;
for(j=; j<=n; j++)
lx[i]=max(lx[i],Map[i][j]);
} for(int x=; x<=n; x++)
{
for(i=; i<=n; i++)
slack[i]=INF;
while()
{
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(DFS(x))//若可加入直接跳出
break;
int d=INF;
for(i=; i<=n; i++)
{
if(!visy[i])
d=min(slack[i],d);//否则根据贪心的思想,找到最小的可行标杆修改值
}
for(i=; i<=n; i++)//修改lx标杆
{
if(visx[i])
lx[i]-=d;
}
for(i=; i<=n; i++)//修改ly标杆
{
if(visy[i])
ly[i]+=d;
else
slack[i]-=d;//slack由lx[x]+ly[y]-Map[x][y]而来;ly中未标记过的值不变,lx中已标记过的值减少,则slack应减少
}
}
}
int ans=;
for(i=;i<=n;i++)
{
ans+=Map[linker[i]][i];
}
return ans;
} int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=; i<=n; i++)
{
for(int j=; j<=n; j++)
scanf("%d",&Map[i][j]);
} int ans=KM();
printf("%d\n",ans);
}
return ;
}
HDU 2255 奔小康赚大钱 KM算法的简单解释的更多相关文章
- hdu 2255 奔小康赚大钱--KM算法模板
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:有N个人跟N个房子,每个人跟房子都有一定的距离,现在要让这N个人全部回到N个房子里面去,要 ...
- hdu 2255奔小康赚大钱 KM算法模板
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=2255 一,KM算法:(借助这个题写一下个人对km的理解与km模板) KM算法主要是用来求解图的最优匹 ...
- HDU - 2255 奔小康赚大钱 KM算法 模板题
HDU - 2255 题意: 分配n所房子给n个家庭,不同家庭对一所房子所需缴纳的钱是不一样的,问你应当怎么分配房子,使得最后收到的钱最多. 思路: KM算法裸题.上模板 #include <i ...
- hdu 2255 奔小康赚大钱 KM算法
看到这么奇葩的题目名我笑了,后来这么一个裸的KM调了2小时我哭了…… 这是个裸的KM算法,也没什么多说的,主要是注意多组数据时,每次都要把各种数组清空啊,赋值啊什么的,反正比较麻烦.至于为什么调了2小 ...
- HDU 2255 奔小康赚大钱 KM算法题解
KM算法求的是完备匹配下的最大权匹配,是Hungary算法的进一步,由于Hungary算法是最大匹配的算法,不带权. 经典算法,想不出来的了,要參考别人的.然后消化吸收吧. 由于真的非常复杂的算法. ...
- hdu 2255 奔小康赚大钱 (KM)
奔小康赚大钱Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- HDU 2255 奔小康赚大钱 KM裸题
#include <stdio.h> #include <string.h> #define M 310 #define inf 0x3f3f3f3f int n,nx,ny; ...
- 二分图最大权匹配问题&&KM算法讲解 && HDU 2255 奔小康赚大钱
作者:logosG 链接:https://www.cnblogs.com/logosG/p/logos.html (讲解的KM算法,特别厉害!!!) KM算法: 现在我们来考虑另外一个问题:如果每个员 ...
- HDU 2255 奔小康赚大钱(带权二分图最大匹配)
HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...
随机推荐
- INSTALL_FAILED_NO_MATCHING_ABIS
在运行写好的cocos的demo时候,安装出现以下问题: 后来发现是因为自己用cygwin生成的x86的.so文件跟自己的魅族3机器CPU不适配!!! 参考:http://stackoverflow. ...
- bug记录_document.defaultview.getcomputedstyle()
页面中使用document.defaultview.getcomputedstyle()在火狐下取不到值. 原本方法现在$(document).ready()中,换到window.onload里就可以 ...
- Android 安装镜像
1. 关机 2. 按住音量减键和电源键,直到进入fastboot模式 3. 连接上PC 4. PC端输入sudo fastboot devices验证已识别到设备 5. PC端输入sudo fastb ...
- rabbitmq(1)-入门
参考: documentation: https://www.rabbitmq.com/documentation.htmldemo: https://www.rabbitmq.com/getstar ...
- ElasticSearch(5)-Mapping
一.Mapping概述 映射 为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成全文本(Full-text)或精确的字符串值,Elasticsearch需要知道每个字段里面都包含了 ...
- [ An Ac a Day ^_^ ] hdu 2553 N皇后问题 搜索
曾经想过一天一AC 坚持下来的确不容易额 (我是没坚持下来 尽量以后坚持…… 经典的N皇后问题 搜索的入门问题 学了这么久竟然一直没敲过 今天敲一下…… 这道题也不是很简单额 纯暴力就超时了 要打一下 ...
- js 有关字符串的函数 以及一些和字符串有关的知识
JS自带函数 concat 将两个或多个字符的文本组合起来,返回一个新的字符串. var a = "hello"; var b = ",world"; var ...
- StretchBlt 提高图片显示质量的方法
通过SetStretchMode(STRETCH_HALFTONE)实现,同时注意重新设置画刷起点 LRESULT CMainDlg::OnPaint(UINT uMsg, WPARAM wParam ...
- tableview 代理方法详解
typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) { UITableViewCellAccessoryNone, // 不显示任何图标 ...
- Mozilla Firefox的各级版本链接
Mozilla Firefox的各级版本链接 及语言 https://ftp.mozilla.org/pub/firefox/releases/