当前位置: 首页 > 编程日记 > 正文

图论:关于二分图的总结(转载)

二分图是这样一个图,它的顶点可以分类两个集合XY,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。

 

  最大匹配:图中包含边数最多的匹配称为图的最大匹配。

  完美匹配:如果所有点都在匹配边上,称这个最大匹配是完美匹配。

  最小覆盖:最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和其中一个点关联。

 

  最小路径覆盖:用尽量少的不相交简单路径覆盖有向无环图G的所有结点。解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的iY结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m

 

  最大独立集问题: 在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值.如果图G满足二分图条件,则可以用二分图匹配来做.最大独立集点数 = N - 最大匹配数

最小点覆盖=最大匹配数

  额,现在还没想到如何证明……

一、匈牙利算法

G=(V,{R})是一个无向图。如顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属两个不同的子集。则称图G为二分图。

         给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。

         选择这样的边数最大的子集称为图的最大匹配问题(maximal matching problem) 

         如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。

最大匹配在实际中有广泛的用处,求最大匹配的一种显而易见的算法是:先找出全部匹配,然后保留匹配数最多的。但是这个算法的复杂度为边数的指数级函数。因此,需要寻求一种更加高效的算法。

匈牙利算法是求解最大匹配的有效算法,该算法用到了增广路的定义(也称增广轨或交错轨):若P是图G中一条连通两个未匹配顶点的路径,并且属M的边和不属M的边(即已匹配和待匹配的边)P上交替出现,则称P为相对于M的一条增广路径。

由增广路径的定义可以推出下述三个结论:

         1.   P的路径长度必定为奇数,第一条边和最后一条边都不属于M

         2.   P经过取反操作(即非M中的边变为M中的边,原来M中的边去掉)可以得到一个更大的匹配M’

         3.   MG的最大匹配当且仅当不存在相对于M的增广路径。

从而可以得到求解最大匹配的匈牙利算法:

         (1)M为空

         (2)找出一条增广路径P,通过取反操作获得更大的匹配M’代替M

         (3)重复(2)操作直到找不出增广路径为止

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int maxn=110;
 6 int n,m,a,b,ans,cnt,fir[maxn],nxt[maxn],to[maxn],mat[maxn];
 7 bool vis[maxn];
 8 void addedge(int a,int b){
 9     nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;
10 }
11 bool Solve(int node){
12     vis[node]=true;
13     for(int i=fir[node];i;i=nxt[i]){
14         if(mat[to[i]]&&(vis[mat[to[i]]]||!Solve(mat[to[i]])))continue;
15         mat[to[i]]=node;
16         return true;
17     }
18     return false;
19 }
20 int main(){
21     freopen("flyer.in","r",stdin);
22     freopen("flyer.out","w",stdout);
23     scanf("%d%d",&n,&m);
24     while(scanf("%d%d",&a,&b)!=EOF)
25         addedge(a,b);
26     for(int i=1;i<=n-m;i++){
27         memset(vis,0,sizeof(vis));
28         if(Solve(i))
29             ans++;
30     }
31     printf("%d\n",ans);
32     return 0;
33 }

  题目是”飞行员匹配“。

 

二、KM算法:

二分图最优匹配:对于二分图的每条边都有一个权(非负),要求一种完备匹配方案,使得所有匹配边的权和最大,记做最优完备匹配。(特殊的,当所有边的权为1时,就是最大完备匹配问题)

解二分图最优匹配问题可用穷举的方法,但穷举的效率=n!,所以我们需要更加优秀的算法。

先说一个定理:设M是一个带权完全二分图G的一个完备匹配,给每个顶点一个可行顶标(ix顶点的可行标用lx[i]表示,第jy顶点的可行标用ly[j]表示),如果对所有的边(i,j) in G,都有lx[i]+ly[j]>=w[i,j]成立(w[i,j]表示边的权),且对所有的边(i,j) in M,都有lx[i]+ly[j]=w[i,j]成立,则M是图G的一个最优匹配。

KuhnMunkras算法(即KM算法)流程:

         (1)初始化可行顶标的值

         (2)用匈牙利算法寻找完备匹配

         (3)若未找到完备匹配则修改可行顶标的值

         (4)重复(2)(3)直到找到相等子图的完备匹配为止

KM算法主要就是控制怎样修改可行顶标的策略使得最终可以达到一个完美匹配,首先任意设置可行顶标(如每个X节点的可行顶标设为它出发的所有弧的最大权,Y节点的可行顶标设为0),然后在相等子图中寻找增广路,找到增广路就沿着增广路增广。而如果没有找到增广路呢,那么就考虑所有现在在匈牙利树中的X节点(记为S集合),所有现在在匈牙利树中的Y节点(记为T集合),考察所有一段在S集合,一段在not T集合中的弧,取       delta = min {l(xi)+l(yj)-w(xi,yj) , | xi in S, yj   in not T}    。明显的,当我们把所有S集合中的l(xi)减少delta之后,一定会有至少一条属于(S, not T)的边进入相等子图,进而可以继续扩展匈牙利树,为了保证原来属于(S,T )的边不退出相等子图,把所有在T集合中的点的可行顶标增加delta。随后匈牙利树继续扩展,如果新加入匈牙利树的Y节点是未盖点,那么找到增广路,否则把该节点的对应的X匹配点加入匈牙利树继续尝试增广。

复杂度分析:由于在不扩大匹配的情况下每次匈牙利树做如上调整之后至少增加一个元素,因此最多执行n次就可以找到一条增广路,最多需要找n条增广路,故最多执行n^2次修改顶标的操作,而每次修改顶标需要扫描所有弧,这样修改顶标的复杂度就是O(n^2)的,总的复杂度是O(n^4)的。

     对于not T的每个元素yj,定义松弛变量slack(yj) =min{l(xi)+l(yj)-w(xi,yj), | xi in S},很明显每次的delta = min{slack(yj), | yj   in not T},每次增广之后用O(n^2)的时间计算所有点的初始slack,由于生长匈牙利树的时候每条弧的顶标增量相同,因此修改每个slack需要常数时间(注意在修改顶标后和把已盖Y节点对应的X节点加入匈牙利树的时候是需要修改slack的)。这样修改所有slack值时间是O(n)的,每次增广后最多修改n次顶标,那么修改顶标的总时间降为O(n^2)n次增广的总时间复杂度降为O(n^3)。事实上这样实现之后对于大部分的数据可以比O(n^4)的算法快一倍左右。

利用二分图匹配的匈牙利算法和KM算法,我们可以求解大部分的关于二分图的问题,它们提供了求解最大匹配和最优匹配的有效算法,在具体编程时我们只要多注意优化,我们就可以得出求解这类问题的有效方法,从而可以对这类实际问题进行有效合理的解决。

另一种说法:

KM算法(转)

        KM算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转化为求完备匹配的问题的。设顶点Xi的顶标为A[i],顶点Yi的顶标为B [i],顶点XiYj之间的边权为w[i,j]。在算法执行过程中的任一时刻,对于任一条边(i,j)A[i]+B[j]>=w[i,j]始终 成立。KM算法的正确性基于以下定理:
   若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。
   这个定理是显然的。因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和;如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和。所以相等子图的完备匹配一定是二分图的最大权匹配。
   初始时为了使A[i]+B[j]>=w[i,j]恒成立,令A[i]为所有与顶点Xi关联的边的最大权,B[j]=0。如果当前的相等子图没有完备匹配,就按下面的方法修改顶标以使扩大相等子图,直到相等子图具有完备匹配为止。
   我们求当前相等子图的完备匹配失败了,是因为对于某个X顶点,我们找不到一条从它出发的交错路。这时我们获得了一棵交错树,它的叶子结点全部是X顶点。现在我们把交错树中X顶点的顶标全都减小某个值dY顶点的顶标全都增加同一个值d,那么我们会发现:
 两端都在交错树中的边(i,j)A[i]+B[j]的值没有变化。也就是说,它原来属于相等子图,现在仍属于相等子图。
 两端都不在交错树中的边(i,j)A[i]B[j]都没有变化。也就是说,它原来属于(或不属于)相等子图,现在仍属于(或不属于)相等子图。
 X端不在交错树中,Y端在交错树中的边(i,j),它的A[i]+B[j]的值有所增大。它原来不属于相等子图,现在仍不属于相等子图。
 X端在交错树中,Y端不在交错树中的边(i,j),它的A[i]+B[j]的值有所减小。也就说,它原来不属于相等子图,现在可能进入了相等子图,因而使相等子图得到了扩大。
   现在的问题就是求d值了。为了使A[i]+B[j]>=w[i,j]始终成立,且至少有一条边进入相等子图,d应该等于min{A[i]+B[j]-w[i,j]|Xi在交错树中,Yi不在交错树中}
   以上就是KM算法的基本思路。但是朴素的实现方法,时间复杂度为O(n4)——需要找O(n)次增广路,每次增广最多需要修改O(n)次顶 标,每次修改顶标时由于要枚举边来求d值,复杂度为O(n2)。实际上KM算法的复杂度是可以做到O(n3)的。我们给每个Y顶点一个松弛量函数 slack,每次开始找增广路时初始化为无穷大。在寻找增广路的过程中,检查边(i,j)时,如果它不在相等子图中,则让slack[j]变成原值与A [i]+B[j]-w[i,j]的较小值。这样,在修改顶标时,取所有不在交错树中的Y顶点的slack值中的最小值作为d值即可。但还要注意一点:修改 顶标后,要把所有的slack值都减去d

原文:http://www.360doc.com/content/11/0718/14/3701281_134273282.shtml

 

转载于:https://www.cnblogs.com/TenderRun/p/5321381.html

相关文章:

动态加载的html没有js效果,JS利用html5实现loadding动态加载效果代码实例

51前端window.οnlοadfunction(){var Loading function (canvas, options) {this.canvas document.getElementById(canvas);this.options options;};Loading.prototype{constructor: Loading,show: function(){var canvas this.canvas,begin this.options.begin,old thi…

iOS 自动布局框架 – Masonry 详解

来源&#xff1a;伯乐在线 - 刘小壮 如有好文章投稿&#xff0c;请点击 → 这里了解详情 如需转载&#xff0c;发送「转载」二字查看说明 目前iOS开发中大多数页面都已经开始使用Interface Builder的方式进行UI开发了&#xff0c;但是在一些变化比较复杂的页面&#xff0c;还是…

GDC2016 Epic Games【Bullet Train】 新风格的VR-FPS的制作方法

追求“舒适”和“快感”的VR游戏设计方法http://game.watch.impress.co.jp/docs/news/20160318_749016.html【Bullet Train】演讲的状况在游戏的创造历史上&#xff0c;有那种决定性的创新&#xff0c;以及高完成度的作品&#xff0c;对于FPS风格来说&#xff0c;【DOOM】就是这…

例4-1和例4-2和例4-3

public class ComputerCircleArea{ public static void main(String args[]){ double radius; double area; radius163.16; area3.14*radius*radius; System.out.printf("半径是%5.3f的圆的面积:\n%5.3f\n",radius,area); }} class Circle{ double radius; doubl…

html中的两种标记,如何在html选项标记中实现两种不同的对齐?

下面是一个单空间js解决方案,与scott everden的jquery示例一起使用。我只在firefox中测试过,但这应该足够开始了。javascriptvar MIN_SPACES_BETWEEN_VALS 3;function mkOption(left, right, total){var str left;var spaces total - left.length - right.length;for(x 0;x…

html标签(2)--有序列表与无序列表

有一些内容形式&#xff0c;用div来实现非常麻烦&#xff0c;也不适合 例如一些表格形式 无序列表 ul 代表列表 li 代表列表中的项 list-style 控制列表的样式 有序列表 ol 代表列表 li 代表列表中的项 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN…

Swift3实现的绘制股票K线库, FastImageCache提升图片的加载和渲染速度,Chameleon颜色框架

代码1:用Swift3实现的绘制股票K线库 for iOS & macOS代码地址&#xff1a;网页链接代码2:FastImageCache是Path团队开发的一个开源库&#xff0c;用于提升图片的加载和渲染速度&#xff0c;让基于图片的列表滑动起来更顺畅。代码地址&#xff1a;网页链接代码3&#xff1a;…

传智播客还收费 兄弟会都是免费的

【传智播客还收费 兄弟会都是免费的 兄弟连兄弟会it开发培训 www.itxdh.net 企鹅群&#xff1a;499956522 高端人才培养就到【兄弟连兄弟会it开发培训】纯免费的高端IT人才培养】 传智播客&#xff0c;一个多么具有戏剧性的词眼&#xff0c;以前张孝祥老师建校的初衷就是为了让…

用计算机的英语造句process,process的用法总结大全

process的意思n. 过程,工序,做事方法,工艺流程vt. 加工,处理,审阅,审核vi. 列队行进adj. 经过特殊加工(或处理)的变形&#xff1a;过去式: processed&#xff1b; 现在分词&#xff1a;processing&#xff1b; 过去分词&#xff1a;processed&#xff1b;process用法process可以…

iOS进阶之页面性能优化

作者: hi_xgb 地址: http://www.jianshu.com/p/1b5cbf155b31 前言 在软件开发领域里经常能听到这样一句话&#xff0c;“过早的优化是万恶之源”&#xff0c;不要过早优化或者过度优化。我认为在编码过程中时刻注意性能影响是有必要的&#xff0c;但凡事都有个度&#xff0c;不…

LabelMe图像数据集下载

Download MATLAB Toolbox for the LabelMe Image Database 利用Matlab Toolbox工具箱下载图像库 一、下载Matlab Toolbox工具箱 1. Github repository We maintain the latest version of the toolbox on github. To pull the latest version, make sure that "git" …

win8计算机管理没有用户组,Win8右键计算机管理提示“该文件没有与之关联的程序”怎么办?...

最近有Win8用户反映&#xff0c;右键计算机管理的时候&#xff0c;出现提示“该文件没有与之关联的程序来执行该操作”&#xff0c;这让用户非常苦恼。那么&#xff0c;Win8右键计算机管理提示“该文件没有与之关联的程序”怎么办呢&#xff1f;下面&#xff0c;我们就一起往下…

Objective-C 自动生成文档工具:appledoc

来源&#xff1a;iOS_小松哥 www.jianshu.com/p/fd4d8d6b6177 如有好文章投稿&#xff0c;请点击 → 这里了解详情 由于最近琐事比较多&#xff0c;所以好久没有写文章了。今天我们聊一聊Objective-C自动生成文档。 做项目的人多了&#xff0c;就需要文档了。手工写文档是一件…

linux命令--提升

查看系统进程&#xff1a;top 查看磁盘空间&#xff1a; df -h 查询系统负载: uptime , 以下显示输入uptime的信息&#xff1a; 04:03:58 up 10 days, 13:19, 1 user, load average: 0.54, 0.40, 0.20 1.当前时间 04:03:58 2.系统已运行的时间 10 days, 13:19 3.前在线用户…

git 从远程主服务器当中创建新分支

现有版本; h20, h28&#xff0c;h26,i8 h28&#xff0c;h26,i8是从H20下面创建的。 需求: 从H28下面创建新分支继续开发。 思路&#xff1a; 所有代码均是放置到H20上仓库当中&#xff0c;首先下载H20完整仓库&#xff0c;也就是.git文件夹当中内容&#xff0c;其本质是一个ZIP…

涉密计算机用户账号设置审批表,北京邮电大学涉密计算机配置审批表.PDF

北京邮电大学涉密计算机配置审批表北京邮电大学涉密计算机配置审批表使用部门 品牌型号涉密计算机类型 ?台式机 ?便携机 资产编号用途 ?科研 ?办公 ?其他 配置日期硬盘序列号中央处理器硬盘容量CPU基本配置 内 存显示器品牌型号MAC 地址操作系统版本 操作系统安装时间放置…

Oracle 正则表达式

ORACLE中的支持正则表达式的函数主要有下面四个&#xff1a;1&#xff0c;REGEXP_LIKE &#xff1a;与LIKE的功能相似2&#xff0c;REGEXP_INSTR &#xff1a;与INSTR的功能相似3&#xff0c;REGEXP_SUBSTR &#xff1a;与SUBSTR的功能相似4&#xff0c;REGEXP_REPLACE &#x…

制作 Swift 和 Objective-C Mixed 的 Pod

来源&#xff1a;南栀倾寒 www.jianshu.com/p/c7623c31d77b 如有好文章投稿&#xff0c;请点击 → 这里了解详情 知识背景 What is CocoaPods&#xff08;https://guides.cocoapods.org/using/getting-started.html&#xff09; What did CocoaPods do&#xff1f;&#x…

SearchRequestBuilder常用方法说明

SearchRequestBuilder常用方法说明 (1) setIndices(String... indices)&#xff1a;上文中描述过&#xff0c;参数可为一个或多个字符串&#xff0c;表示要进行检索的index&#xff1b;(2) setTypes(String... types)&#xff1a;参数可为一个或多个字符串&#xff0c;表示要进…

计算机知识课后反思,计算机硬件和软件知识课后反思

计算机硬件和软件知识课后反思《计算机系统组成》—计算机硬件和软件知识一课是七年级信息技术中《信息技术基础》里的知识。在学习这之前&#xff0c;学生虽然都使用过计算机&#xff0c;但对于计算机的系统组成、主机内的硬件知识基本知之甚少。但是对这些知识学生又充满了好…

iOS超全开源框架、项目和学习资料汇总:UI篇

2017-01-30 iOS巍 CocoaChina原文 上下拉刷新控件 1. MJRefresh --仅需一行代码就可以为UITableView或者CollectionView加上下拉刷新或者上拉刷新功能。可以自定义上下拉刷新的文字说明。&#xff08;推荐&#xff09; 2. SVPullToRefresh --下拉刷新控件4500star&#xff0c;…

NYOJ 90 —— 求正整数n划分为若干个正整数的划分个数

整数划分 时间限制&#xff1a;3000 ms | 内存限制&#xff1a;65535 KB描述将正整数n表示成一系列正整数之和&#xff1a;nn1n2…nk&#xff0c; 其中n1≥n2≥…≥nk≥1&#xff0c;k≥1。 正整数n的这种表示称为正整数n的划分。求正整数n的不 同划分个数。 例如正整数6有如…

调整命令行的列数和行数 mode con: cols=100 lines=10000

mode con: cols100 lines10000转载于:https://www.cnblogs.com/passer1991/archive/2013/03/25/2980285.html

写一个 iOS 复杂表单的正确姿势

前言 这几天项目的新需求中有个复杂的表单界面&#xff0c;在做的过程中发现要比想象中复杂很多&#xff0c;有好多问题需要处理。有很多东西值得写下来好好梳理下。 需求分析&#xff1a; 6创建网店1.png上图便是UI根据需求给的高保真&#xff0c; 我们先根据这张图片来描述一…

2014计算机三级网络技术,2014计算机三级网络技术综合题解题思路

2014计算机三级网络技术综合题解题思路,全部自码第一小题 IP地址的计算公式正常IP地址计算&#xff1a;已知IP地址&#xff1b;子网掩码&#xff1b;地址类别&#xff1a;A类地址&#xff1a;1—126(00)B类地址&#xff1a;128—191(10)C类地址&#xff1a;192—223(110) D类地…

word 生成HTML

View Code 1 string wordPath Server.MapPath("/Fileword/" FileUpload1.FileName); 2 string htmlPath Server.MapPath("/Fileword/测试.html");3 //上传word文件4 FileUpload1.SaveAs(wordP…

CCF系列之画图(201409-2)

试题编号&#xff1a; 201409-2试题名称&#xff1a; 画图时间限制&#xff1a; 1.0s内存限制&#xff1a; 256.0MB问题描述&#xff1a; 问题描述在一个定义了直角坐标系的纸上&#xff0c;画一个(x1,y1)到(x2,y2)的矩形指将横坐标范围从x1到x2&#xff0c;纵坐标范围从y1到y2…

大连理工计算机专业导师,大连理工大学计算机科学与技术学院研究生导师简介-申彦明...

大连理工大学计算机科学与技术学院研究生导师简介-申彦明大连理工大学 免费考研网/2016-05-04申彦明院系&#xff1a;计算机科学与技术学院办公电话&#xff1a;无电子信箱&#xff1a;shendlut.edu.cn更新时间&#xff1a;2014-4-4其他专业&#xff1a;计算机系统结构个人简介…

iOS基础问答面试题连载-附答案

2017-02-02 timhbw CocoaChina以下是一些自己收集的比较基础的问题&#xff08;大神可以忽略&#xff09;&#xff0c;附上答案&#xff0c;方便大家阅读。俗话说得好&#xff0c;基础不牢&#xff0c;地动山摇。文章末尾会提供PDF版的文档&#xff0c;方便大家木有网的时候也可…

一个非常简单的 ASP.NET MVC 示例:长轮询(又叫:反向 AJAX,英文名:Comet)实现...

关于 长轮询&#xff08;又叫&#xff1a;反向 AJAX&#xff0c;英文名&#xff1a;Comet&#xff09;的介绍&#xff0c;请查看&#xff1a;反向Ajax&#xff0c;第1部分&#xff1a;Comet介绍 下面是代码实现&#xff1a; UI: <p><input type"button" onc…