二分图---染色法(判断二分图),匈牙利算法(二分图的最大匹配) //概念,应用场景,判定证明,算法思路,示例

目录

 二分图概念

二分图应用场景

如何判定一个图是否可以划分成二分图

    证明

染色法

原理步骤

时间复杂度

算法思路

 例子   

匈牙利算法

 概念

匈牙利使用算法前提,场景

时间复杂度

 算法思路

例子 


 二分图概念

        二分图是图论中的一个重要概念,指的是一个图的顶点集可以被分为两个互不相交的子集,并且图中的每条边都连接两个不同子集中的顶点。换句话说,如果一个图是二分图,那么可以将图中的所有顶点分为两组,使得每条边的两个端点分别属于不同的组。

二分图应用场景

  1. 匹配问题:在二分图中,匹配问题是指找到一种边的子集,使得图中每个顶点都与子集中的某条边相邻。在实际应用中,可以用于匹配求职者和工作岗位、学生和导师等场景。

  2. 任务分配:在二分图中,任务分配问题是指将一组任务分配给一组工人,使得每个任务只被分配给一个工人,每个工人最多只能完成一个任务。这在实际生活中可以用于工作排班、资源分配等问题。

  3. 流网络:在网络流问题中,二分图可以表示一种特殊的流网络,其中顶点集分为源点集和汇点集,边表示从源点到汇点的流量路径,用于建模输送网络中的流量分配和优化问题。

  4. 电路布线:在电路布线问题中,可以将待连接的元器件和连接线分别看作二分图中的顶点和边,通过最小化连接线的长度或者最小化连接的总成本来优化电路的布线。

  5. 等等

如何判定一个图是否可以划分成二分图

        二分图当且仅当图中不含有奇数环

    证明

  • 充分性:(不含有奇数环的图可以划分成二分图)

       使用一种方法(染色法),随意选择 A 图中一个点 a ,将其分到集合 A_x ,然后将其邻接的所有点分到集合 A_y ,再将分到 A_y 的点的邻接点分到 A_x 。以此类推,因为图中不含有奇数环,所以分类过程中一定没有矛盾

        如何证明没有矛盾:

        反证:假设图中不含有奇数环,但分类过程中出现了矛盾。

        假设有一个偶环 a_1,\ a_2\ ,a_3\ ...\ a_{2k} \ \ k\in N^+ (任意相邻两点有边连接,且 a_1 和 a_{2k} 之间有一条边相邻)。该环中出现了矛盾,使用染色法时, a_1 和 a_{2k} 被分到同一个类别 A_x

        首先,我们先对该环按顺序依次进行分类,a_1 分到 A_xa_2 分到 A_ya_3 分到 A_x 。

        以此类推,可知编号为奇数的都属于 A_x 集合,编号为偶数的都属于 A_y 集合。因此 , a_{2k} 被分到 A_y 。并且,a_1 相邻 a_{2k} ,a_{2k}也应该分到 A_y

        与假设不符,因此假设错误,说明图中不含有奇数环,分类过程中一定没有矛盾。

  • 必要性:(二分图不含有奇数环)

        反证:假设该二分图含有一个奇数环a_1,\ a_2\ ,a_3\ ...\ a_{2k-1} \ \ k\in N^+,任意相邻两点有边连接,且 a_1 和 a_{2k-1} 之间有一条边相邻。

        假设 a_1\in A_x 集合,则 a_2\in A_y ,a_3\in A_x。以此类推,可知编号为奇数的都属于 A_x 集合,编号为偶数的都属于 A_y 集合。

        那么 a_1 和 a_{2k-1} 都属于 A_x 集合,a_1 和 a_{2k-1} 之间有一条边。与二分图同一个集合中的点不相连矛盾,因此假设错误。二分图不存在奇数环。



染色法

判断一个图是不是二分图。

原理步骤

  1. 选择一个起始顶点,将其染成一种颜色(比如红色)。
  2. 将与该顶点相邻的顶点染成另一种颜色(比如蓝色)。
  3. 依次对与 已染色的顶点 相邻的未染色顶点进行染色,要求相邻顶点的颜色不能相同。
  4. 如果在染色的过程中,发现有相邻的两个顶点被染成了相同的颜色,则说明该图不能划分成二分图;否则,当所有顶点都被染色后,该图可以划分成二分图。

时间复杂度

        O(m+n)

算法思路

        可以使用bfs,dfs,并查集遍历图。 

伪代码 BFS版:

main:

        Queue q

        循环n次  // 有可能有多个连通图

                如果当前点 t 没被访问过,q <- t

                对 t 进行染色

                进行bfs()

bfs():

        while q 不空:

                t <- 取出队头

                遍历 t 的邻接的点:

                        如果邻接的点的色与 t 的颜色相同或者是个自环 说明不能构成一个二分图

                        否则:将邻接点染色,并加入队列

 例子   

860. 染色法判定二分图 - AcWing题库

给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环。

请你判断这个图是否是二分图。

输入格式

第一行包含两个整数 n 和 m。

接下来 m 行,每行包含两个整数 u 和 v,表示点 u 和点 v 之间存在一条边。

输出格式

如果给定图是二分图,则输出 Yes,否则输出 No

数据范围

1≤n,m≤10^5

输入样例:

4 4
1 3
1 4
2 3
2 4

输出样例:

Yes

dfs:AcWing 860. 染色法判定二分图 - JAVA -DFS - AcWing 

并查集:AcWing 860. 看不懂dfs和bfs可以来康康并查集 - AcWing 

使用BFS + 数组模拟邻接表: 

import java.io.*;
import java.util.*;class Main{static int N = 100010;static int n,m,idx;static int[] h = new int[N];static int[] e = new int[2*N];static int[] ne = new int[2*N];static int[] w = new int[N]; // 染色记录static boolean[] st = new boolean[N]; // 标记是否染过色static Queue<int[]> q = new LinkedList<>();public static void main(String[] args) throws IOException{BufferedReader in = new BufferedReader(new InputStreamReader(System.in));String[] s = in.readLine().split(" ");n = Integer.parseInt(s[0]);m = Integer.parseInt(s[1]);Arrays.fill(h,-1);int flag = 1;while(m-->0){s = in.readLine().split(" ");int a = Integer.parseInt(s[0]);int b = Integer.parseInt(s[1]);add(a,b);add(b,a);  }for(int i=1;i<=n;i++) { // 有可能有多个连通图,因此每个点都需要遍历if(!st[i]) { // 如果没被染色q.add(new int[]{i,1}); // 染色为1st[i] = true;if(color()==-1) flag = 0; // 如果有奇数环,返回-1}}if(flag==0) System.out.println("No");else System.out.println("Yes");}// 染色public static int color(){while(!q.isEmpty()){int[] t = q.poll();int u = t[0]; // 点int weight = t[1]; // 被染色的值for(int i=h[u];i!=-1;i=ne[i]){ // 对邻接点进行染色int j = e[i];if(w[j]==weight||j==u) return -1; // 如果该点的颜色与邻接点相同或者有自环,直接返回if(!st[j]){ // 如果该点没被染色w[j] = 3-weight; // 染色q.add(new int[]{j,w[j]});  st[j] = true; // 表示为已经被访问过} }}return 1;}// 添加边public static void add(int a,int b){e[idx] = b;ne[idx] = h[a];h[a] = idx++;}
}

匈牙利算法

 概念

  •  匹配:在图论中,一个「匹配」是一个边的集合,其中任意两条边都没有公共顶点。
  • 最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。
  • 完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。
  • 交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。
  • 增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替 路称为增广路(agumenting path)。

匈牙利使用算法前提,场景

        已知该图是二分图,求最大匹配数。

        可以想象成:二分图,左边集合是女生,右边是男生,两个集合之间男生和女生连接了线,表明这两人可以成为恋爱关系。但是一个男生只能和一个女生谈恋爱,求最多能成为恋爱关系的情侣数量。

        

  1. 任务分配:在任务与执行者之间存在偏好关系时,可以使用匈牙利算法将任务分配给执行者,使得每个执行者最多承担一个任务,并且尽可能多的任务得到执行。

  2. 最大流问题:匈牙利算法可以用作最大流算法的一部分,用于寻找增广路径,从而找到最大流量。

  3. 资源分配:在资源有限的情况下,可以使用匈牙利算法来优化资源的分配,以满足不同资源需求的任务或需求者。

时间复杂度

        O(mn),实际一般小于mn 

 算法思路

        该二分图中,一个集合A_1 中有 n_1 个顶点,另一个集合A_2 中有 n_2 个顶点。

        st[ ] :

伪代码:

// 用 A_1 匹配 A_2 ,只需要记录 A_1 到 A_2 的单向边

mian():

循环 n1 次:

        对该点进行匹配 find(t)

find(t):

        遍历 t 点所有能匹配上的 A_2 中的所有点:

                如果 当前匹配到的点 i 没有匹配过 或者 i 点被匹配了,但是匹配到的 A_1 中的那个点可以匹配 A_2 中另外的点

                那么点 i 和 t 点匹配成功

        遍历完还没匹配到则匹配失败

例子 

 给定一个二分图,其中左半部包含 n1 个点(编号 1∼n1),右半部包含 n2 个点(编号 1∼n2),二分图共包含 m 条边。

数据保证任意一条边的两个端点都不可能在同一部分中。

请你求出二分图的最大匹配数。

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

二分图的最大匹配:所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数。

输入格式

第一行包含三个整数 n1、 n2 和 m。

接下来 m 行,每行包含两个整数 u 和 v,表示左半部点集中的点 u 和右半部点集中的点 v 之间存在一条边。

输出格式

输出一个整数,表示二分图的最大匹配数。

数据范围

1≤n1,n2≤500,
1≤u≤n1,
1≤v≤n2,
1≤m≤10^5

输入样例:

2 2 4
1 1
1 2
2 1
2 2

输出样例:

2
// 通过n1集合匹配n2集合,只需记录n1到n2的边
import java.io.*;
import java.util.*;class Main{static int N = 510, M = 100010;static int n1,n2,m,idx,res;static int[] h = new int[N];static int[] e = new int[M];static int[] ne = new int[M];static boolean[] st = new boolean[N]; // n2中的点是否匹配了static int[] match = new int[N]; // 记录n2集合中的点匹配的是n1中的哪个点public static void main(String[] args) throws IOException{BufferedReader in = new BufferedReader(new InputStreamReader(System.in));String[] s = in.readLine().split(" ");n1 = Integer.parseInt(s[0]);n2 = Integer.parseInt(s[1]);m = Integer.parseInt(s[2]);Arrays.fill(h,-1);while(m-->0){s = in.readLine().split(" ");int a = Integer.parseInt(s[0]);int b = Integer.parseInt(s[1]);add(a,b); // 只需要添加单向边}for(int i=1;i<=n1;i++){Arrays.fill(st,false); // 被考虑过的n2集合中的点也可以重新被下一个n1中的点考虑if(find(i)) res++; // 找n2中能匹配的}System.out.println(res);}// 进行匹配public static boolean find(int u){for(int i=h[u];i!=-1;i=ne[i]){int j = e[i];if(!st[j]){st[j] = true; // 被当前点考虑到了if(match[j]==0||find(match[j])){ // 如果该点没有匹配或者该点的上一个匹配的点可以匹配到另外一个match[j] = u; // 将j匹配给ireturn true; // 匹配成功                    } }}return false;}// 添加边public static void add(int a,int b){e[idx] = b;ne[idx] = h[a];h[a] = idx++;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/708566.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java四大引用类型

四大引用类型 从JDK 1.2版本开始&#xff0c;对象的引用被划分为4种级别&#xff0c;从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为&#xff1a;强引用、软引用、弱引用和虚引用 不同的引用类型&#xff0c;主要体现的是对象不同的可达性&#xff08;r…

【vue3学习笔记】Suspense组件;vue3中的其它改变

尚硅谷Vue2.0Vue3.0全套教程丨vuejs从入门到精通 课程 P167节 《Suspense组件》笔记 想要学习suspense&#xff0c;先来了解静态组件与异步组件。 静态引入与异步引入&#xff1a; 在network中将网速调慢&#xff0c;观察在静态引入和异步引入模式下&#xff0c;两个组件的加载…

CI/CD笔记.Gitlab系列.`gitlab-ci.yml`中的头部关键字

CI/CD笔记.Gitlab系列 gitlab-ci.yml中的头部关键字 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.ne…

【MySQL】主从同步原理、分库分表

主从同步原理 1. 主从同步原理 MySQL 经常先把命令拷入硬盘的日志&#xff0c;再执行日志的命令&#xff0c;这样的好处&#xff1a; 日志的位置固定&#xff0c;拷入硬盘的开销不大&#xff1b;将命令先准备好&#xff0c;而不是边读边执行&#xff0c;性能更好&#xff0c;…

Google Genie vs OpenAI Sora:互动世界模型之争,谁将引领AI的未来?

近年来&#xff0c;生成式AI异军突起&#xff0c;从文字到图像&#xff0c;再到视频&#xff0c;它们的创造力令人瞩目。 但今天&#xff0c;我们要介绍Google Genie&#xff0c;不仅仅满足于生成静态的内容。 它能把单一的图片提示&#xff0c;变成一个你可以亲身参与的互动…

【系统分析师】-软件工程

1、信息系统的生命周期 1、四阶段划分 立项阶段&#xff1a;企业全局、形成概念、需求分析。包含【系统分析师】-系统规划-CSDN博客开发阶段&#xff1a;总体规划--系统分析--设计--实施--验收运维阶段&#xff1a;通过验收、移交之后消亡阶段&#xff1a;更新改造、功能扩展…

K8S部署postgresql

&#xff08;作者&#xff1a;陈玓玏&#xff09; 一、前置条件 已部署k8s&#xff0c;服务端版本为1.21.14 二、部署postgresql 拉取镜像&#xff0c;docker pull postgres&#xff0c;不指定版本&#xff0c;自动从docker hub拉取最新版本&#xff1b;配置configmap&…

【UE 材质】制作加载图案

目录 效果 步骤 一、形成圆环 二、使圆环转起来 效果 步骤 一、形成圆环 新建一个材质&#xff0c;这里命名为“M_Loading” 打开“M_Loading”&#xff0c;设置混合模式为半透明&#xff0c;着色模型为无光照&#xff0c;勾选双面 下面开始先创建一个圆环&#xff0c;将…

OpenHarmony Docker移植实践

Docker简介 从操作系统诞生之日起&#xff0c;虚拟化技术就不断的演进与发展&#xff0c;结合目前云原生的发展态势&#xff0c;容器无疑是其中的重要一环。 Docker是一个开源的软件项目&#xff0c;可以在Linux操作系统上提供一层额外的抽象&#xff0c;让用户程序部署在一个…

[CSS]文字旁边的竖线以及布局知识

场景&#xff1a;文字前面常见加竖线。 .center-title { 常见内容color: #FFF;font-family: "Source Han Sans CN";font-size: 50px;font-style: normal;font-weight: 700;line-height: normal;position: relative; 要定位left: 16px; 这里是想拉开间距margin-b…

Redisson限流算法

引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.12.3</version> </dependency>建议版本使用3.15.5以上 使用 这边写了一个demo示例&#xff0c;定…

Vue+Flask电商后台管理系统

在这个项目中&#xff0c;我们将结合Vue.js前端框架和python后端框架Flask&#xff0c;打造一个功能强大、易于使用的电商后台管理系统 项目演示视频&#xff1a; VueFlask项目 目录 前端环境&#xff08;Vue.js&#xff09;&#xff1a; 后端环境&#xff08;python-Flask&…

Mysql REGEXP正则运算符

# 邮箱h开头 mysql> select email form xxx where email REGEXP ^h;

改进的yolo交通标志tt100k数据集目标检测(代码+原理+毕设可用)

YOLO TT100K: 基于YOLO训练的交通标志检测模型 在原始代码基础上&#xff1a; 修改数据加载类&#xff0c;支持CoCo格式&#xff08;使用cocoapi&#xff09;&#xff1b;修改数据增强&#xff1b;validation增加mAP计算&#xff1b;修改anchor&#xff1b; 注: 实验开启weig…

YOLOv9 最简训练教学!

一、代码及论文链接&#xff1a; 代码链接&#xff1a;GitHub - WongKinYiu/yolov9: Implementation of paper - YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information 论文链接&#xff1a;https://arxiv.org/abs/2402.13616 二、使用步骤 1…

淘宝商品数据爬取商品信息采集数据分析API接口详细步骤展示(含测试链接)

01 数据采集 数据采集是数据可视化分析的第一步&#xff0c;也是最基础的一步&#xff0c;数据采集的数量和质量越高&#xff0c;后面分析的准确的也就越高&#xff0c;我们来看一下淘宝网的数据该如何爬取。点此获取淘宝API测试key&密钥 淘宝网站是一个动态加载的网站&a…

前端css、js、bootstrap、vue2.x、ajax查漏补缺(1)

学到的总是忘&#xff0c;遇到了就随手过来补一下 1.【JS】innerHTML innerHTML属性允许更改HTML元素的内容可以解析HTML标签 2.【CSS】display: none 设置元素不可见&#xff0c;不占空间&#xff0c;约等于将元素删除一样&#xff0c;只是源代码还存在 3.【CSS】行内样式 4.【…

工作微信统一管理(还带监管功能)

1.会话页面(可统一管理多个微信号、聚合聊天、手动搜索添加好友、通过验证请求、查看好友的朋友圈等) 2.聊天历史(可查看 所有聊天记录&#xff0c;包括手机.上撤回、删除的消息) 3.群发助手(可以一 -次群发多个好友和群&#xff0c;还可以选择定时发送&#xff0c;目前还在内测…

PlantUML简介

PlantUML简介 plantUML是一款开源的UML图绘制工具&#xff0c;支持通过文本来生成图形&#xff0c;使用起来非常高效。可以支持时序图、类图、对象图、活动图、思维导图等图形的绘制。你可以在IDEA中安装插件来使用PlantUML, 或者在Visual Studio Code中安装插件。 也可以在dra…

数据库|三地五中心,TiDB POC最佳实践探索!

目录 一、POC测试背景 //测试环境信息 二、流量单元化控制 //需求 //解决方案 三、跨城获取TSO的影响与探索 //问题描述与初步分析 //优化方案 四、灾难恢复与流量切流 //需求 //pd leader 切换 //region leader t切换 五、写在最后 一、POC测试背景 在某地震多发省…