算法学习系列(二十四):二分图

目录

  • 引言
  • 一、二分图
  • 二、染色法
  • 三、匈牙利算法

引言

这个二分图作为平常我是不怎么知道的,但是在算法竞赛中还是能用得到的。本文主要介绍了染色法:用来判断如否为二分图,匈牙利算法:求出二分图最大匹配数。

一、二分图

二分图:在两个集合中,集合之间没有边。如下图所示,两个橙色代表两个集合,集合间的点没有边,不同集合间的点才可能有边
在这里插入图片描述

在这里插入图片描述

二、染色法

用处:用来判断是否为二分图
思想:遍历所有的点,如果没染过,那就把该集合的点全染了,如果染的过程中发现冲突,那就将flag置为false
可以通过一个点就将该集合中的所有点全染了,如下图所示。
在这里插入图片描述

题目描述:

给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环。请你判断这个图是否是二分图。输入格式
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 u 和 v,表示点 u 和点 v 之间存在一条边。输出格式
如果给定图是二分图,则输出 Yes,否则输出 No。数据范围
1≤n,m≤105输入样例:
4 4
1 3
1 4
2 3
2 4
输出样例:
Yes

示例代码:

#include <cstdio>
#include <cstring>
#include <iostream>using namespace std;const int N = 1e5+10, M = N * 2;  //因为是无向图int n, m;
int h[N], e[M], ne[M], idx;
int color[N];void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}bool dfs(int u, int c)
{color[u] = c;for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];if(!color[j])  //没有染{if(!dfs(j, 3 - c)) return false;}else if(color[j] == c) return false;  //染了但是染的是相同的颜色}return true;
}int main()
{memset(h, -1, sizeof h);scanf("%d%d", &n, &m);while(m--){int a, b;scanf("%d%d", &a, &b);add(a, b), add(b, a);}bool flag = true;for(int i = 1; i <= n; ++i){if(color[i]) continue;if(!dfs(i, 1)) {flag = false;break;}}if(flag) puts("Yes");else puts("No");return 0;
}

三、匈牙利算法

用处:判断一个二分图中成功匹配的最大数。成功匹配:没有两条边共用一个点
思想:有两个图左、右,如果左一匹配了,右一,然后左二只能匹配右一,那就让左一换一个匹配,再让左二匹配右一,如果换不了就不换了,然后就这样一次遍历所有的点

题目描述:

给定一个二分图,其中左半部包含 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≤105输入样例:
2 2 4
1 1
1 2
2 1
2 2
输出样例:
2

示例代码:

#include <cstdio>
#include <cstring>
#include <iostream>using namespace std;const int N = 510, M = 1e5+10;int n1, n2, m;
int h[N], e[M], ne[M], idx;
int match[N];  //代表n2所匹配的是谁
bool st[N];void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}bool find(int u)
{for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];if(st[j]) continue;st[j] = true;if(match[j] == 0 || find(match[j]))  //如果没有匹配或者匹配的找到另一个了{match[j] = u;  // 匹配return true;}}return false;
}int main()
{memset(h, -1, sizeof h);scanf("%d%d%d", &n1, &n2, &m);while(m--){int a, b;scanf("%d%d", &a, &b);add(a, b);}int res = 0;for(int i = 1; i <= n1; ++i){memset(st, 0, sizeof st);  // 如果不置为false,那么就不能要求匹配过的更换了if(find(i)) res++;}printf("%d\n", res);return 0;
}

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

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

相关文章

Linux例行性工作 at和crontab命令

1&#xff0c;例行性工作 例行性工作 —— 在某一时刻&#xff0c;必须要做的事情 —— 定时任务 &#xff08;比如&#xff1a;闹钟&#xff09; 例行性工作分为两种&#xff1a;“单一的例行性工作 at”和“循环的例行性工作 crontab” 2&#xff0c;单一执行的例行性工作 …

HTML--JavaScript--引入方式

啊哈~~~基础三剑看到第三剑&#xff0c;JavaScript HTML用于控制网页结构 CSS用于控制网页的外观 JavaScript用于控制网页的行为 JavaScript引入方式 引入的三种方式&#xff1a; 外部JavaScript 内部JavaScript 元素事件JavaScript 引入外部JavaScript 一般情况下网页最好…

真假转换之间 tr

文章目录 真假转换之间 tra-z小写全部转换为大写A-Z大写全部转换为小写貌似起名可以用这个移除文件中的所有空格更多信息 真假转换之间 tr Linux tr 命令用于转换或删除字符。 tr 命令可以从标准输入读取数据&#xff0c;经过字符串转译后&#xff0c;将结果输出到标准输出。…

AGV小车磁导航传感器CNS-MGS-080N磁条布置方法

AGV小车磁导航传感器CNS-MGS-080N通过检测磁场信号强度&#xff0c;来判断此磁条相对于传感器位置。CNS-MGS-080N传感器使用8个点检测信号&#xff0c;模拟16点传感器信号进行输出。 本文重点介绍AGV小车磁导航传感器CNS-MGS-080N磁条布置方法。 1、 磁条规格 磁条型号 CNS-M…

京东数据分析-2023年度大家电行业数据分析(含空调、冰箱、洗衣机、平板电视品类)

2023年度&#xff0c;京东平台上大家电市场的需求疲软&#xff0c;行业整体销售呈下滑趋势。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;2023年大家电行业大盘的销量累计约为6100万&#xff0c;同比下滑约15%&#xff1b;年度销额累计1400亿&#xff0c;同比下滑约…

【ELK 学习】ElasticSearch

ELK&#xff1a;ElasticSearch存储&#xff0c;Logstash收集&#xff0c;Kibana展示 版本较多&#xff0c;使用时需要版本匹配&#xff0c;还需要和mysql版本匹配&#xff08;elastic官网给了版本对应关系&#xff09; 本次使用的版本es6.8.12 filebeat 轻量级的数据收集工具 …

设计模式——1_5 享元(Flyweight)

今人不见古时月&#xff0c;今月曾经照古人 ——李白 文章目录 定义图纸一个例子&#xff1a;可以复用的样式表绘制表格降本增效&#xff1f;第一步&#xff0c;先分析 变化和不变的地方第二步&#xff0c;把变化和不变的地方拆开来第三步&#xff1a;有没有办法共享这些内容完…

Android Studio下载及安装和Gradle的配置(非常详细)从零基础入门到精通,看完这一篇就够了

文章目录 下载安装修改Sdk的位置创建项目修改Gradle的位置查看AS版本工具栏–View项工具栏–Build下的功能说明Build Variants视图说明下载模拟器&#xff08;avd&#xff09;/安卓虚拟设备 屏幕熄灭功能关闭虚拟设备功能删除自己开发的应用软件将开发的应用运行到虚拟设备上。…

高精度AGV小车N/S极磁条导航传感器CNS-MGS-080N参数配置操作方法

高精度AGV小车N/S极磁条导航传感器CNS-MGS-080N主要运用于自主导航机器人、室内室外巡检机器人、自主导航运输车AGV(AGC)、自动手推车等自主导航设备&#xff0c;完成自主导航设备的预设运行路线检测及定位。基于预设磁轨迹的导航方式是自主移动平台如AGV、巡检机器人、无轨货架…

添加边界值分析测试用例

1.1创建项目成功后会自动生成封装好的函数&#xff0c;在这些封装好的函数上点击右键&#xff0c;添加边界值分析测试用例&#xff0c;如下图所示。 1.2生成的用例模版是不可以直接运行的&#xff0c;需要我们分别点击它们&#xff0c;让它们自动生成相应测试用例。如下图所示&…

跨境电商账号频繁?你的IP可能“不干净”了

疫情促进了跨境电商行业的加速发展&#xff0c;许多卖家也抓住了这波流量红利&#xff0c;跨境电商月入数万&#xff0c;数十万甚至数百万的造福神话也不断在上演&#xff0c;但由于国内外电商运营模式不同&#xff0c;多店运营、用户数据收集、刷单等行为都受到了国外平台的严…

【CV】使用 matplotlib.pyplot 绘制统计图、坐标系原点在不同的位置和添加辅助点和辅助线

1. 数据 这里使用模拟数据 import random import matplotlib.pyplot as pltvalues [i * random.random() for i in range(100)] values[0.0,0.2596417433881839,1.0607353016866907, ...89.24287458194097,78.48300255421442]2.坐标原点-左下角 坐标系原点在左下角&#xf…