二分图匹配(匈牙利算法)

1。一个二分图中的最大匹配数等于这个图中的最小点覆盖数

König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数。如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖所有的边。

2。最小路径覆盖=最小路径覆盖=|G|-最大匹配数

 在一个N*N的有向图中,路径覆盖就是在图中找一些路经,使之覆盖了图中的所有顶点,
 且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,
 那么恰好可以经过图中的每个顶点一次且仅一次);如果不考虑图中存在回路,那么每每条路径就是一个弱连通子集.

由上面可以得出:

1.一个单独的顶点是一条路径;
 2.如果存在一路径p1,p2,......pk,其中p1 为起点,pk为终点,那么在覆盖图中,顶点p1,p2,......pk不再与其它的
   顶点之间存在有向边.

最小路径覆盖就是找出最小的路径条数,使之成为G的一个路径覆盖.

路径覆盖与二分图匹配的关系:最小路径覆盖=|G|-最大匹配数;

3。二分图最大独立集=顶点数-二分图最大匹配

独立集:图中任意两个顶点都不相连的顶点集合。

现在来介绍下匈牙利算法了,我们先提一下几个概念,下面M是图G=(V,E)的一个匹配(这里先假设它还不是最大匹配)。

EXample:若顶点集合为  ,边集合为 。Xi与Yi为二分图的两个部分。

假设边  已经在匹配M上。

下面是概念

M-交错路:p是G的一条通路,如果p中的边为属于M中的边与不属于M但属于G中的边交替出现,则称p是一条M-交错路。如:路径

  

M-饱和点:对于 ,如果v与M中的某条边关联,则称v是M-饱和点,否则称v是非M-饱和点。如 都属于M-饱和点,而其它点都属于非M-饱和点。

M-可增广路:p是一条M-交错路,如果p的起点和终点都是非M-饱和点,则称p为M-可增广路。如 (不要和流网络中的增广路径弄混了)。

求最大匹配的一种显而易见的算法是:先找出全部匹配,然后保留匹配数最多的。但是这个算法的时间复杂度为边数的指数级函数。因此,需要寻求一种更加高效的算法。下面介绍用增广路求最大匹配的方法(称作匈牙利算法,匈牙利数学家Edmonds于1965年提出)。
 
增广路的定义(也称增广轨或交错轨):
若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径。
由增广路的定义可以推出下述三个结论:
(1)P的路径个数必定为奇数第一条边和最后一条边都不属于M。
(2)将M和P进行取反操作可以得到一个更大的匹配 M' 
(3)M为G的最大匹配当且仅当不存在M的增广路径。
 
算法轮廓:
  • (1)置M为空
  • (2)找出一条增广路径P,通过异或操作获得更大的匹配M' 代替M
  • (3)重复(2)操作直到找不出增广路径为止

下面举个例子:

Machine Schedule

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3444    Accepted Submission(s): 1669

Problem Description
As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduling problems differ widely in the nature of the constraints that must be satisfied and the type of schedule desired. Here we consider a 2-machine scheduling problem.

There are two machines A and B. Machine A has n kinds of working modes, which is called mode_0, mode_1, …, mode_n-1, likewise machine B has m kinds of working modes, mode_0, mode_1, … , mode_m-1. At the beginning they are both work at mode_0.

For k jobs given, each of them can be processed in either one of the two machines in particular mode. For example, job 0 can either be processed in machine A at mode_3 or in machine B at mode_4, job 1 can either be processed in machine A at mode_2 or in machine B at mode_4, and so on. Thus, for job i, the constraint can be represent as a triple (i, x, y), which means it can be processed either in machine A at mode_x, or in machine B at mode_y.


Obviously, to accomplish all the jobs, we need to change the machine's working mode from time to time, but unfortunately, the machine's working mode can only be changed by restarting it manually. By changing the sequence of the jobs and assigning each job to a suitable machine, please write a program to minimize the times of restarting machines.
 
Input
The input file for this program consists of several configurations. The first line of one configuration contains three positive integers: n, m (n, m < 100) and k (k < 1000). The following k lines give the constrains of the k jobs, each line is a triple: i, x, y.

The input will be terminated by a line containing a single zero.

 
Output
The output should be one integer per line, which means the minimal times of restarting machine.
 
Sample Input
5 5 10 0 1 1 1 1 2 2 1 3 3 1 4 4 2 1 5 2 2 6 2 3 7 2 4 8 3 3 9 4 3 0
 
Sample Output
3
 
Source
 
Recommend
Ignatius.L
 
 
题目大意;有两台机器A和B以及N个需要运行的任务。每台机器有M种不同的模式,而每个任务都恰好在一台机器上运行。如果它在机器A上运行,则机器A需要设置为模式xi,如果它在机器B上运行,则机器A需要设置为模式yi。每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式需要重启一次。请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少。

二分图的最小顶点覆盖数=最大匹配数

本题就是求最小顶点覆盖数的。

每个任务建立一条边。

最小点覆盖就是求最少的点可以连接到所有的边。本题就是最小点覆盖=最大二分匹配数

注意一点就是:题目说初始状态为0,所以如果一个任务有一点为0的边不要添加。因为不需要代价

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,k;
int G[][];
int vis[];
int link[];
int DFS(int u)//从左边开始找增广路径
{
for(int v=;v<m;v++)
{
if(G[u][v]&&!vis[v])
{
vis[v]=;
if(!link[v]||DFS(link[v]))//找增广路,反向
{
link[v]=u;
return ;
}
}
}
return ;
}
int main()
{
int i;
while(~scanf("%d",&n))
{
if(!n)
break;
scanf("%d%d",&m,&k);
memset(G,,sizeof(G));
memset(link,,sizeof(link));
for(i=;i<k;i++)
{
int _,x,y;
scanf("%d%d%d",&_,&x,&y);
G[x][y]=;
}
int ans=;
for(i=;i<n;i++)//At the beginning they are both work at mode_0.所以下标直接从1开始
{
memset(vis,,sizeof(vis));
ans+=DFS(i);
}
printf("%d\n",ans);
}
}

二分图最大匹配(匈牙利算法)简介& Example hdu 1150 Machine Schedule的更多相关文章

  1. 匈牙利算法模板 hdu 1150 Machine Schedule(二分匹配)

    二分图:https://blog.csdn.net/c20180630/article/details/70175814 https://blog.csdn.net/flynn_curry/artic ...

  2. HDU - 1045 Fire Net (二分图最大匹配-匈牙利算法)

    (点击此处查看原题) 匈牙利算法简介 个人认为这个算法是一种贪心+暴力的算法,对于二分图的两部X和Y,记x为X部一点,y为Y部一点,我们枚举X的每个点x,如果Y部存在匹配的点y并且y没有被其他的x匹配 ...

  3. hdu 1150 Machine Schedule(二分匹配,简单匈牙利算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1150 Machine Schedule Time Limit: 2000/1000 MS (Java/ ...

  4. hdu 1150 Machine Schedule(最小顶点覆盖)

    pid=1150">Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/327 ...

  5. HDU 1045 - Fire Net - [DFS][二分图最大匹配][匈牙利算法模板][最大流求二分图最大匹配]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1045 Time Limit: 2000/1000 MS (Java/Others) Mem ...

  6. UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法

    二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...

  7. HDU 1150 Machine Schedule (最小覆盖,匈牙利算法)

    题意: 有两台不同机器A和B,他们分别拥有各种运行模式1~n和1~m.现有一些job,需要在某模式下才能完成,job1在A和B上需要的工作模式又可能会不一样.两台机器一开始处于0模式,可以切换模式,但 ...

  8. Ural1109_Conference(二分图最大匹配/匈牙利算法/网络最大流)

    解题报告 二分图第一题. 题目描写叙述: 为了參加即将召开的会议,A国派出M位代表,B国派出N位代表,(N,M<=1000) 会议召开前,选出K队代表,每对代表必须一个是A国的,一个是B国的; ...

  9. HDU1068 (二分图最大匹配匈牙利算法)

    Girls and Boys Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

随机推荐

  1. (转)js中then方法说明

    javascript中的then方法说明: then()方法是异步执行.  意思是:就是当.then()前的方法执行完后再执行then()内部的程序,这样就避免了,数据没获取到等的问题.  语法:pr ...

  2. mysql 5.7 Could not load driverClass com.mysql.cj.jdbc.Driver

    参考: http://www.manongjc.com/article/24424.html https://blog.csdn.net/kingscoming/article/details/788 ...

  3. 数据结构和算法(Java版)快速学习(线性表)

    线性表的基本特征: 第一个数据元素没有前驱元素: 最后一个数据元素没有后继元素: 其余每个数据元素只有一个前驱元素和一个后继元素. 线性表按物理存储结构的不同可分为顺序表(顺序存储)和链表(链式存储) ...

  4. Vue知识整理8:条件、URL、点击

    1.通过v-if实现对条件的判断和执行: 2.通过v-bind:href实现对url地址的绑定,其中url写在data中: 3.通过@click="click1"实现点击事件,其中 ...

  5. kafka多线程消费

    建立kafka消费类ConsumerRunnable ,实现Runnable接口: import com.alibaba.fastjson.JSON; import com.alibaba.fastj ...

  6. 13 oracle数据库坏块-逻辑坏块(模拟/修复)

    13 oracle数据库坏块-逻辑坏块 逻辑数据坏块的场景1)oracle bug也可能导致逻辑坏块的产生. 特别是parallel dml. 例如:Bug 5621677 Logical corru ...

  7. Failure to find com.oracle:ojdbc6:jar:11.2.0.1.0

    报错原因:oracle的ojdbc.jar是收费的,maven的中央仓库是没有的,需要下载到本地,然后打包进maven仓库 1.下载ojdbc6-11.2.0.1.0.jar包 http://cent ...

  8. 应用安全 - Web安全 - 远程控制管理工具 - 汇总

    菜刀 蚁剑 冰蝎 DarkCommet ADT windows/upexec/reverse_tcp set PEXEC xxx

  9. python 并发编程 多进程 队列目录

    python 并发编程 多进程 队列 python 并发编程 多进程 生产者消费者模型介绍 python 并发编程 多进程 生产者消费者模型总结 python 并发编程 多进程 JoinableQue ...

  10. 第四周Java实验总结&学习总结

    实验二 Java简单类与对象 实验目的 掌握类的定义,熟悉属性.构造函数.方法的作用,掌握用类作为类型声明变量和方法返回值: 理解类和对象的区别,掌握构造函数的使用,熟悉通过对象名引用实例的方法和属性 ...