【算法基础:搜索与图论】3.6 二分图(染色法判定二分图匈牙利算法)

news2024/11/27 18:00:33

文章目录

  • 二分图介绍
  • 染色法判定二分图
    • 例题:860. 染色法判定二分图
  • 匈牙利匹配
    • 二分图最大匹配
    • 匈牙利匹配算法思想
    • 例题:861. 二分图的最大匹配

二分图介绍

https://oi-wiki.org/graph/bi-graph/

二分图是图论中的一个概念,它的所有节点可以被分为两个独立的集合,每个边的两个端点分别来自这两个不同的集合
换句话说,二分图中不存在连接同一集合内两个节点的边

在这里插入图片描述

在这里插入图片描述

染色法判定二分图

如何判断一个图是二分图?
当且仅当图中不含奇数环。(奇数环指的是环中边的个数是奇数)(因为每一条边都是从一个集合走到另一个集合,只有走偶数次才有可能回到同一个集合。)


染色:相邻的节点的颜色不一样。
在这里插入图片描述
因为没有奇数环,所以染色过程是一定不会发生矛盾的。

时间复杂度是 O ( n + m ) O(n + m) O(n+m) , n 表示点数,m 表示边数。

例题:860. 染色法判定二分图

https://www.acwing.com/activity/content/problem/content/926/

在这里插入图片描述

使用 dfs 对图中各个节点染色,染色过程中不发生冲突即为二分图。

import java.util.*;

public class Main {
    static final int N = 100005;
    static List<Integer>[] g = new ArrayList[N];
    static int[] color = new int[N];

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt();
        // 建图
        Arrays.setAll(g, e -> new ArrayList<Integer>());
        for (int i = 0; i < m; ++i) {
            int u = sc.nextInt(), v = sc.nextInt();
            g[u].add(v);
            g[v].add(u);
        }

        // 图可能由多个非连通的子图构成。因此,应该对每一个尚未访问过的点都进行一次深度优先搜索。
        boolean f = true;
        for (int i = 1; i <= n; ++i) {
            if (color[i] == 0 && !dfs(i, 1)) {
                f = false;
                break;
            }
        }
        System.out.println(f? "Yes": "No");
    }

    static boolean dfs(int x, int c) {
        boolean res = true;
        color[x] = c;
        for (int y: g[x]) {
            if (color[y] == 0) res &= dfs(y, 3 - c);
            else if (color[y] == color[x]) return false;
        }
        return res;
    }
}

匈牙利匹配

二分图最大匹配

**二分图最大匹配**
翻译成人话就是——
给定一个二分图 G,即分左右两部分,各部分之间的点没有边连接,要求选出一些边,使得这些边没有公共顶点,且边的数量最大

匈牙利匹配算法思想

两个集合的点数分别是 n1 , n2。
枚举 n1 , 尝试 i 是否可以找到一个 j 完成匹配,匹配成功就 ++cnt。

所以重点是 find(i) 方法:
对每个 i ,枚举 i 相邻的所有 j —— 如果 j 没有被匹配就直接返回 true;如果 j 被匹配了,就尝试现在和 j 匹配的另一个 i 能不能换一个 j,能换就换一个然后返回 true;否则返回 false。

时间复杂度是 O ( n ∗ m ) O(n * m) O(nm),n 表示点数,m 表示边数。

例题:861. 二分图的最大匹配

https://www.acwing.com/activity/content/problem/content/927/
在这里插入图片描述

重点是理解数组 matchst 的含义,以及方法 find(x) 的写法和使用。

import java.util.*;

public class Main {
    static final int N = 505;
    static int[][] g = new int[N][N];
    static int[] match = new int[N];		// match记录集合2中各个点匹配的集合1的点是哪个
    static boolean[] st = new boolean[N];	// st表示集合2中的点有没有被匹配
    static int n1, n2;

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        n1 = sc.nextInt();
        n2 = sc.nextInt();
        int m = sc.nextInt();
        // 建图
        for (int i = 0; i < m; ++i) {
            int u = sc.nextInt(), v = sc.nextInt();
            g[u][v] = 1;        // 左边的 u 和 右边的 v 之间有一条边
        }

        int cnt = 0;
        for (int i = 1; i <= n1; ++i) {
            Arrays.fill(st, false);		// 重置st
            if (find(i)) ++cnt;
        }

        System.out.println(cnt);
    }

    static boolean find(int x) {
        for (int j = 1; j <= n2; ++j) {
            if (!st[j] && g[x][j] == 1) {
                st[j] = true;
                // 如果 j 还没有匹配或者当前使用 j 的 x 可以让出去
                if (match[j] == 0 || find(match[j])) {
                    match[j] = x;
                    return true;
                }
            }
        }
        return false;
    }
}

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

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

相关文章

群组变量选择、组惩罚group lasso套索模型预测新生儿出生体重风险因素数据和交叉验证、可视化...

原文链接&#xff1a;http://tecdat.cn/?p25158 本文介绍具有分组惩罚的线性回归、GLM和Cox回归模型的正则化路径。这包括组选择方法&#xff0c;如组lasso套索、组MCP和组SCAD&#xff0c;以及双级选择方法&#xff0c;如组指数lasso、组MCP&#xff08;点击文末“阅读原文”…

htmlCSS-----背景样式

目录 前言&#xff1a; 背景样式 1.背景颜色 background-color 2.背景图片 background-image 背景的权重比较 代码示例&#xff1a; 前言&#xff1a; 很久没写文章了&#xff0c;会不会想我呢&#xff01;今天我们开始学习html和CSS的背景样式以及文字样式&#xff…

井川里予是谁呢?是中国人,还是日本人?

井川里予是抖音上的一个网红&#xff0c;名字叫庞欣然。 井川里予不是日本人&#xff0c;她是地地道道的中国人。 井川里予2001年6月出生于浙江省杭州市&#xff0c;现在在广东湛江发展。她毕业于浙江经济职业技术学院&#xff0c;抖音女网红&#xff0c;粉丝高达一千多万&…

Day 64:集成学习之 AdaBoosting (2. 树桩分类器)

做了一个超类, 用于支持不同的基础分类器. 这里为了减少代码量, 只实现了树桩分类器.树桩分类器每次只将数据分成两堆, 与决策树相比, 简单至极. 当然, 这里处理的是实型数据, 而 ID3 处理的是符号型数据. 抽象分类器代码&#xff1a; package dl;import java.util.Random;im…

图像处理之LoG算子(高斯拉普拉斯)

LoG算子&#xff08;高斯拉普拉斯算子&#xff09; LoG算子是由拉普拉斯算子改进而来。拉普拉斯算子是二阶导数算子&#xff0c;是一个标量&#xff0c;具有线性、位移不变性&#xff0c;其传函在频域空间的原点为0。所有经过拉普拉斯算子滤波的图像具有零平均灰度。但是该算子…

栈OJ(C++)

文章目录 1.最小栈2.栈的压入、弹出序列3.逆波兰表达式&#xff08;后缀表达式&#xff09;求值3.1后缀表达式求值3.2中缀表达式转后缀表达式3.3带有括号的中缀表达式转后缀表达式 1.最小栈 class MinStack { public:MinStack(){}void push(int val){_st.push(val);//empty放在…

MQTT网关 5G物联网网关 PLC控制工业网关

MQTT网关&#xff0c;两个以上的节点之间通信的新型网关&#xff0c;网络节点之间通过互连来实现双向通信。支持PLC协议转MQTT&#xff0c;实现plc数据采集上云&#xff0c;物联网云平台对接&#xff0c;广泛应用于工业自动化plc远程监测控制。 计讯物联5G MQTT物联网网关TG463…

设计模式-单例模式进阶

在前面的文章(设计模式-单例模式)中&#xff0c;我们分别介绍了四种单例设计模式&#xff0c;包括普通恶汉式单例、双重检查锁单例(DCL)、静态内部类单例以及枚举单例。但是&#xff0c;这四种模式还有一些问题我们没有仔细分析&#xff0c;以至于我们无法深入分析他们的优点以…

【面试题】万字总结MYSQL面试题

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 1、三大范式 2、DML 语句和 DDL 语句区别 3、主键和外键的区别 4、drop、delete、truncate 区别 5、基础架构 6、MyISAM 和 InnoDB 有什么区别&#xff1f; 7、推荐自增id作为…

【mac系统】mac系统调整妙控鼠标速度

当下环境&#xff1a; mac系统版本&#xff0c;其他系统应该也可以&#xff0c;大家可以自行试下&#xff1a; 鼠标 mac妙控鼠标&#xff0c;型号A1657 问题描述&#xff1a; 通过mac系统自带的鼠标速度调节按钮&#xff0c;调到最大后还是感觉移动速度哦过慢 问题解决&…

若依微服务整合activiti7.1.0.M6

若依微服务3.6.3版本整合activiti7&#xff08;7.1.0.M6&#xff09; 目前有两种办法集成activiti7 放弃activiti7新版本封装的API&#xff0c;使用老版本的API&#xff0c;这种方式只需要直接集成即可&#xff0c;在7.1.0.M6版本中甚至不需要去除security的依赖。不多介绍&a…

日常问题记录-Android-Bug-OOM

大家好哇&#xff0c;我是梦辛工作室的灵&#xff0c;最近的项目中&#xff0c;我又遇到了一个bug&#xff0c;就是我写了一个类 将app会用到的Bitmap缓存起来进行管理&#xff0c;防止OOM嘛&#xff0c;不过莫名奇妙的事情还是发生了&#xff0c;内存依旧上涨&#xff0c;且没…

数据结构day7(2023.7.23)

一、Xmind整理&#xff1a; 二、课上练习&#xff1a; 练习1&#xff1a;结点之间的关系 练习2&#xff1a;二叉树的特殊形态 练习3&#xff1a;满二叉树的形态 练习4&#xff1a;完全二叉树的形态 满二叉树一定是完全二叉树&#xff0c;完全二叉树不一定是满二叉树 练习5&am…

Windows系统自检中断导致存储文件系统损坏的服务器数据恢复案例

服务器数据恢复环境&#xff1a; 一台挂载在Windows server操作系统服务器上的v7000存储&#xff0c;划分了一个分区&#xff0c;格式化为NTFS文件系统&#xff0c;该分区存放oracle数据库。 服务器故障&#xff1a; 服务器在工作过程中由于未知原因宕机&#xff0c;工作人员重…

机器学习深度学习——线性回归

之前已经介绍过线性回归的基本元素和随机梯度下降法及优化&#xff0c;现在把线性回归讲解完&#xff1a; 线性回归 矢量化加速正态分布与平方损失从线性回归到深度网络神经网络图生物学 矢量化加速 在训练模型时&#xff0c;我们常希望能够同时处理小批量样本&#xff0c;所以…

涵子来信——自己的电脑——谈谈想法

大家好&#xff1a; 上一次谈论了苹果的那些事&#xff0c;今天我们来聊聊电脑。 我的第一台电脑现在成了这样子&#xff1a; 很多人以为是我自己拆了电脑做研究&#xff0c;其实是我的第一台电脑&#xff0c;真的坏了。 2021年&#xff0c;我有了属于我自己的第一台电脑&am…

STM32 HAL库串口重映射printf

添加代码 #include "stdio.h" int fputc(int ch, FILE *f) {HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);return ch; }keil设置 实现效果&#xff1a; 打印变量 printf("Hello, I am %s\r\n", "iii"); // printf输出字符…

Kubernetes pv-pvc-nfs-service综合实验

目录 实验&#xff1a;pv-pvc-nfs-service综合实验 实验环境 实验描述 实验拓扑图&#xff1a; 实验步骤&#xff1a; 1、修改nfs服务器的主机名&#xff1a; 2、搭建nfs服务器&#xff1a;(131条消息) 搭建NFS服务器_搭建nfs存储_Claylpf的博客-CSDN博客 3、测试k8s上…

极速跳板机登陆服务器

目录 一&#xff1a;简单登陆跳板器二&#xff1a;一键申请相关的服务器权限三&#xff1a;简化登陆 一&#xff1a;简单登陆跳板器 登陆公司提供的网址&#xff0c; 下载自己的专属RSA密钥。在密钥文件处&#xff0c; 执行登陆指令&#xff1a; ssh -p 36000 -i id_rsa 用户跳…

【MATLAB】 二维绘图,三维绘图的方法与函数

目录 MATLAB的4种二维图 1.线图 2.条形图 3.极坐标图 4.散点图 三维图和子图 1.三维曲面图 2.子图 MATLAB的4种二维图 1.线图 plot函数用来创建x和y值的简单线图 x 0:0.05:30; %从0到30&#xff0c;每隔0.05取一次值 y sin(x); plot(x,y) %若(x,y,LineWidth,2) 可…