Algorithm: 匈牙利算法
例子: poj3041
解法: 摘自http://blog.csdn.net/lyy289065406/article/details/6647040
把方阵看做一个特殊的二分图(以行列分别作为两个顶点集V1、V2,其中| V1|=| V2|)
然后把每行x或者每列y看成一个点,而障碍物(x,y)可以看做连接x和y的边。按照这种思路构图后。问题就转化成为选择最少的一些点(x或y),使得从这些点与所有的边相邻,其实这就是最小点覆盖问题。
再利用二分图最大匹配的König定理:
最小点覆盖数 = 最大匹配数
(PS:最小点覆盖:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖图的所有的边。)
因此本题自然转化为求 二分图的最大匹配 问题
求最大匹配的一种显而易见的算法是:先找出全部匹配,然后保留匹配数最多的。但是这个算法的时间复杂度为边数的指数级函数。
因此,需要寻求一种更加高效的算法——用增广路求最大匹配的方法(匈牙利算法)
增广路的定义(也称增广轨或交错轨):
若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径。
由增广路的定义可以推出下述三个结论:
1、P的路径个数必定为奇数,第一条边和最后一条边都不属于M。
2、将M和P进行取反操作可以得到一个更大的匹配M’
(反操作:把P中的 匹配边 与 非匹配边 互换)
3、M为G的最大匹配当且仅当不存在M的增广路径P
匈牙利算法轮廓:
(1)置M为空
(2)找出一条增广路径P,通过异或操作获得更大的匹配M’代替M
(3)重复(2)操作直到找不出增广路径为止
1 //Memory Time 2 //464K 47MS 3 4 #include<iostream> 5 using namespace std; 6 7 int n,k; //n矩阵规格,k星体数量 8 int V1,V2; //二分图顶点集 9 /*矩阵的行列分别属于二分图的两个顶点集V1、V2,其中行x∈V1,列y∈V2*/ 10 bool grid[501][501]; //存储数据方式:可达矩阵 11 bool vis[501]; //记录V2的点每个点是否已被搜索过 12 int link[501]; //记录 V2中的点y 在 V1中 所匹配的点x的编号 13 int m; //最大匹配数 14 15 /*Hungary Algorithm*/ 16 17 bool dfs(int x) 18 { 19 for(int y=1;y<=V2;y++) 20 if(grid[x][y] && !vis[y]) //x到y相邻(有边) 且 节点y未被搜索 21 { 22 vis[y]=true; //标记节点y已被搜索 23 if(link[y]==0 || dfs(link[y])) //link[y]==0 : 如果y不属于前一个匹配M 24 { //find(link[y] : 如果被y匹配到的节点可以寻找到增广路 25 link[y]=x; //那么可以更新匹配M'(用M替代M') 26 return true; //返回匹配成功的标志 27 } 28 } 29 return false; //继续查找V1下一个x的邻接节点 30 } 31 32 void search(void) 33 { 34 for(int x=1;x<=V1;x++) 35 { 36 memset(vis,false,sizeof(vis)); //清空上次搜索时的标记 37 if(dfs(x)) //从V1中的节点x开始寻找增广路 38 m++; 39 } 40 return; 41 } 42 43 int main(void) 44 { 45 cin>>n>>k; 46 V1=V2=n; 47 48 int x,y; //坐标(临时变量) 49 for(int i=1;i<=k;i++) 50 { 51 cin>>x>>y; 52 grid[x][y]=true; //相邻节点标记 53 } 54 55 /*增广轨搜索*/ 56 57 search(); 58 59 /*Output*/ 60 61 cout<<m<<endl; 62 63 return 0; 64 }
View Code
转载于:https://www.cnblogs.com/yingzhongwen/archive/2013/06/10/3130582.html
Algorithm: 匈牙利算法相关推荐
- 匈牙利算法Hungarian algorithm
匈牙利算法是解决寻找二分图最大匹配的. 匈牙利算法(Hungarian Algorithm)是一种组合优化算法(combinatorial optimization algorithm),换句话说就是 ...
- 匈牙利算法java实现_匈牙利算法(Hungarian Algorithm)
匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法.换句话说就是,在可以接受的时间内去做匹配. 1. 描述问题 给定2个集合A和B,然后将AB中的元素完成一个连线.(这不就是小时候的连线题么 ...
- 匈牙利算法(The Hungarian algorithm) :一个通俗易懂的例子
转自:http://www.hungarianalgorithm.com/examplehungarianalgorithm.php 匈牙利算法:一个例子 我们考虑一个例子,其中四个工作(W1,W2, ...
- 解题报告:luogu P2423 [HEOI2012]朋友圈【最大团转最大点独立集(匈牙利算法+时间戳优化)】
图的最大团:"任意两点之间都有一条边相连"的子图被称为无向图的团,点数最多的团为图的最大团 朋友圈中任意两个点之间都有关系,既是图中的团. 答案就是图中的最大团. 我们如果把B国的 ...
- 二分图最大匹配(匈牙利算法) POJ 3020 Antenna Placement
题目传送门 1 /* 2 题意:*的点占据后能顺带占据四个方向的一个*,问最少要占据多少个 3 匈牙利算法:按坐标奇偶性把*分为两个集合,那么除了匹配的其中一方是顺带占据外,其他都要占据 4 */ 5 ...
- 用匈牙利算法求二分图的最大匹配
转载大神的!! 什么是二分图,什么是二分图的最大匹配,这些定义我就不讲了,网上随便都找得到.二分图的最大匹配有两种求法,第一种是最大流(我在此假设读者已有网络流的知识):第二种就是我现在要讲的匈牙利算 ...
- hdu 4160 Dolls 匈牙利算法求最大匹配
Dolls Time Limit: 2000 ...
- 【Floyed】【匈牙利算法】导弹(jzoj 1610)
题目大意: 有n个城市,有一部分是A国的,有一部分是B国的(小于A国的),A国每个城市都有一枚导弹(只有一枚),炸毁别的城市的时间是到这个城市的距离,请问A国最快要多久可以炸毁B国所有城市 解题思路: ...
- 【HDU - 5943】Kingdom of Obsession(数论,素数间隔结论,构造,思维,匈牙利算法,匹配问题)
题干: There is a kindom of obsession, so people in this kingdom do things very strictly. They name the ...
最新文章
- KDD 2017奖项全公布,华人成最大赢家
- EasyExcel入门使用
- Linux常用命令(第二版) --帮助命令
- 【TI-ONE系列教程(二)】如何使用 TI-ONE 平台内置算子玩转算法大赛
- 分享一个基于事件时间线的Javascript类库-Chronoline
- 在Apache中隐藏Php文件后缀
- DBVisualizer 添加数据库JDBC驱动
- B - 好数 51Nod - 1717
- idea新建一个java项目_创建第一个Java项目(Create First Java Project)
- 简单PHP留言板之二 —— PHP的数据库连接文件
- mysql集群系统_轻松构建Mysql高可用集群系统
- 教你如何用vbs实现微信自动发送消息功能
- 基于vivoY97的Adb驱动程序的安装
- systrace如何使用
- html网页制作的图片打不开,网页中的图片打不开怎么办?原因与解决办法
- 全国省份、城市关联表 mysql(含城市名拼音)
- 认证认可机构收费项目和标准
- COLA之架构演变(一)
- int型整数的最小值和最大值是多少(精确值)
- 机器人在gazebo中使用四轮差速仿真模型时,转向不明显?
热门文章
- Linux文件夹打包发送到本地
- 6月10款超赞的jQuery插件新鲜出炉
- TOP10十大GPS导航手机(有车一族必备手机)
- 《网管员必读——网络组建》(第2版)导读
- linux常用指令_Linux常用指令
- 闭合导线坐标计算表_测量员人员必备:8套工程测量公式计算表,输入参数自动得出结果...
- PCL1.8.0/ Qt5.7.0开发环境配置
- java重写的代码_java tostring方法重写代码示例
- matlab模拟调制过程,模拟信号的调制方式有哪三种?调制与解调是个啥过程
- python保存与加载LGBM模型,并解决报错TypeError: Need at least one training dataset or model file or model string..