算法笔记_137:二分图的最大匹配(Java)
目录
1 问题描述
何为二分图的最大匹配问题?
引用自百度百科:
首先得说明一下何为匹配:
给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。
极大匹配(Maximal Matching)是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。最大匹配(maximum matching)是所有极大匹配当中边数最大的一个匹配。选择这样的边数最大的子集称为图的最大匹配问题。
特别注意:二分图的最大匹配,其图为无权连通图。二分图的最大权分配,其图才是有权连通图,这两者是不同的概念。
2 解决方案
此处采用DFS方法。
具体代码如下:
package com.liuzhen.practice;
import java.util.Scanner;
public class Main {
public static int n = 0, m = 0; //二分图的左边和右边顶点数目
/*
* 参数map:给定的二分图,map[i][j]等于1表示i到j连通,为0则表示不连通
* 参数linked:linked[i] = u表示顶点i与顶点u连接
* 参数start:当前start顶点出发,寻找增广路径
* 函数功能:如果能够找到已顶点start开始的增广路径返回true,否则返回false
*/
public boolean dfs(int[][] map, boolean[] used, int[] linked, int start) {
for(int i = 0;i < m;i++) {
if(used[i] == false && map[start][i] == 1) {
used[i] = true;
if(linked[i] == -1 || dfs(map, used, linked, linked[i])) {
linked[i] = start;
return true;
}
}
}
return false;
}
public int getMaxNum(int[][] map) {
int count = 0;
int[] linked = new int[m];
for(int i = 0;i < m;i++)
linked[i] = -1;
for(int i = 0;i < n;i++) {
boolean[] used = new boolean[m]; //初始化m部分顶点均为被访问
if(dfs(map, used, linked, i)) //从顶点i出发能够得到一条增广路径
count++;
}
return count;
}
public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
int[][] map = new int[n][m];
int k = in.nextInt(); //二分图中边的数目
for(int i = 0;i < k;i++) {
int a = in.nextInt(); //n部分中的顶点
int b = in.nextInt(); //m部分中顶点
map[a][b] = 1;
}
System.out.println(test.getMaxNum(map));
}
}
参考资料:
算法笔记_137:二分图的最大匹配(Java)的更多相关文章
- 算法笔记_023:拓扑排序(Java)
目录 1 问题描述 2 解决方案 2.1 基于减治法实现 2.2 基于深度优先查找实现 1 问题描述 给定一个有向图,求取此图的拓扑排序序列. 那么,何为拓扑排序? 定义:将有向图中的顶点以线性方式进 ...
- 算法笔记_139:二分图的最大权匹配(Java)
目录 1 问题描述 2 解决方案 1 问题描述 何为二分图的最大权匹配问题? 最大权二分匹配问题就是给二分图的每条边一个权值,选择若干不相交的边,得到的总权值最大. 2 解决方案 对于此问题的讲解 ...
- 【算法笔记】二分图与KM算法(当你试图只看蓝书学算法
前言 呜,好久没写博客了,DDL 也有好多,一不留神就轮到我了呜. 看了一眼其它同学写的博客,什么数模啊,什么 CTF 啊,什么 Python 爬虫啊,感觉自己真是越来越菜了呜. 然后在我一愁莫展之际 ...
- 算法笔记_228:信用卡号校验(Java)
目录 1 问题描述 2 解决方案 1 问题描述 当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过Luhn算法来验证 ...
- 算法笔记_138:稳定婚姻问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 何为稳定婚姻问题? 有一个男士的集合Y = {m1,m2,m3...,mn}和一个女士的计划X = {n1,n2,n3,...,nn}.每一个男士有 ...
- 算法笔记_132:最大流量问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 何为最大流量问题? 给定一个有向图,并为每一个顶点设定编号为0~n,现在求取从顶点0(PS:也可以称为源点)到顶点n(PS:也可以称为汇点)后,顶点 ...
- 算法笔记_040:二进制幂(Java)
目录 1 问题描述 2 解决方案 2.1 从左至右二进制幂 2.2 从右至左二进制幂 1 问题描述 使用n的二进制表示,计算a的n次方. 2 解决方案 2.1 从左至右二进制幂 此方法计算a的n次 ...
- 算法笔记_014:合并排序(Java)
1 问题描述 给定一组数据,使用合并排序得到这组数据的非降序排列. 2 解决方案 2.1 合并排序原理简介 引用自百度百科: 合并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Div ...
- 算法笔记_233:二阶魔方旋转(Java)
目录 1 问题描述 2 解决方案 1 问题描述 魔方可以对它的6个面自由旋转. 我们来操作一个2阶魔方(如图1所示): 为了描述方便,我们为它建立了坐标系. 各个面的初始状态如下:x轴正向:绿x轴 ...
随机推荐
- 【贪心大水题】BZOJ3410-[Usaco2009 Dec]Selfish Grazing 自私的食草者
[题目大意] 给出n个区间,问最多选取多少个区间使得它们互相不重叠. [思路] 水题quq改善心情用.按照右端点大小排序,每次更新上一次的右端点,如果当前左端点大于上次右端点可取. #include& ...
- 51nod 1035 最长的循环节 数学
1035 最长的循环节 题目连接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1035 Description 正整 ...
- 【原】Project configuration is not up-to-date with pom.xml
导入一个Maven项目之后发现有一个如下的错误: Project configuration is not up-to-date with pom.xml. Run project configura ...
- X-009 FriendlyARM tiny4412 uboot移植之SD Card用起来Kernel boot起来
<<<<<<<<<<<<<<<<<<<<<<<<< ...
- ExtJS 表单 submit时错误处理
这里不提success,提提Extjs 表单提交的failure方法. 在表单的提交中,当发生异常行为时通常分为三种情况 1. 无法连接到服务器 2. 表单验证错误 3. 业务逻辑错误 对应下面的代码 ...
- ExtJS4.1 ExtJS TabPanel 双击标签关闭该页
/*总觉得 TabPanel 生成的那个关闭按钮太小关闭的时候不太顺手 感觉不方便 所以想双击关闭tab方便些于是在网上找到下面的代码 URL:http://atian25.iteye.com/blo ...
- Ext如何动态添加一行组件
用的column布局,点击一个按钮能添加一行组件,如文本框,有下拉框等. 如: 效果: 实现方法如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...
- AX5511 Boost Converter
GENERAL DESCRIPTION The AX5511 is a current mode step up converter intended for small, low powera ...
- 探究rh6上mysql5.6的主从、半同步、GTID多线程、SSL认证主从复制
http://407711169.blog.51cto.com/6616996/1203973/
- System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
转载:http://www.cnblogs.com/aaa6818162/p/4421305.html 问题现象 IIS应用程序池崩溃(Crash)的特征如下: 1. 从客户端看,浏览器一直处于连接状 ...