c++全套流水账——染色法判断二分图,DFS的实践与应用

2023-11-05 17:30

本文主要是介绍c++全套流水账——染色法判断二分图,DFS的实践与应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近刷题比较多所以分享比较短也很少有视频了大家谅解一下。

染色法判断二分图

关于acwing

什么是二分图

二分图就是只你可以把一个图的点拉到左右两边。
这样它们就会变成两个集合。
那我们把原来图的边保留进这两个集合中。
最后如果我们可以使得这两个集合内部没有任何边,所有边都是两边互相连通的,我们称这个图为二分图。
否则不是二分图。
具体图片:
批注 2020-06-21 183219.png
这个图是二分图吗?
是的。
批注 2020-06-21 183313.png
批注 2020-06-21 183407.png
那这个呢?
不是。
批注 2020-06-21 183501.png
好了我们一会就证明为啥第二个一定不是。

二分图的特性

其实很简单,不能有奇数环。
啥是奇数环?
就是环上的点的数量是奇数。
很简单吧。
那我们是如何证明的呢?
请看下图。
我们把一个奇数环染色。
如果我们的这个是二分图:
那我们由一条边相连的两个点的数应该是不同的。
所以我们用01标完后我们就可以把标0的点放在1号集合。
标1的点放在2号集合。
这就很弱了对吧,我们给一个奇数环标一下就知道了。
批注 2020-06-21 185248.png

染色法判断二分图

依据上面这个原理,我们诞生了染色法。
我们可以把所有点染色撑出0,1。
那怎么染色呢?
没错就是dfs。
dfs搜索可以用来染色。
每次我们判断一下就好了。
判断一下如果我们的两个相邻的点染色相同,则这个图不是二分图。
那这个就很简单了。
我们来看一下具体模板题。
[模板]染色法判定二分图
本题题目:

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

首先我们看一下数据范围。
数据范围是100000,我们再+一个10。

const int N = 100010;

或者:

const int N = 1e5 + 10;

接下来是读入。
这个就很简单了。
我们只要调用add函数存一个邻接表就行了。
注意是邻接表不是邻接矩阵!!!
一:

const int N = 100010;
int n, m, h[N], e[N], ne[N], idx, color[N];
void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

二:

cin >> n >> m;
memset(h, -1, sizeof h);
for(int i = 0; i < m; i ++)
{int a,b;cin >> a >> b;add(a, b);
}

memset那行很重要!如果一不小心忘写了……
就挖了……
批注 2020-06-21 204046.png
有一次就因为这玩意找了半个小时的bug,最后自闭了/误
然后我们来看看中间这个部分。
我们的的dfs有这么几个参数:

  1. u,表示需要染色的点
  2. c,表示染的颜色

所以:

bool dfs(int u, int c)

然后我们来想一下怎么判断。
我们遍历一遍所有点然后看一下染色结果就行了。
这个也没啥好讲的。

bool f = true;
for(int i = 1; i <= n; i ++)
{if(!color[i]){if(!dfs(i, 0)) {f = false;break;}}
}

接着我们来说一下dfs部分怎么写。
首先标记这个点。

color[u] = c;

接下来我们遍历一下。

for(int i = h[u]; i != -1; i = ne[i])

用j表示这个点。

int j = e[i];

接下来看一下这个点有没有染过色,如果没染过就继续往深里执行。
这不就是DFS吗?我好能水

if(!color[j])
{if(!dfs(j, 3 - c)) return false;
}

否则我们判断一下两个点染的色是否一样。
一样就返回false。

else if(color[j] == c) return false;

这里的color就是这个被遍历到的点染的色。
c就是这个点染的色。
所以判断这俩东西是否相等就行了。
最后如果这波都挺下来了就返回true。
dfs部分完整代码:

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;
}

输出我就不水了,大家看完整代码吧。

#include<bits/stdc++.h>using namespace std;const int N = 100010;int n, m;
int h[N], e[N], ne[N], 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()
{cin >> n >> m;for(int i = 0; i < m; i ++){int a,b;cin >> a >> b;add(a, b);}bool f = true;for(int i = 1; i <= n; i ++){if(!color[i]){if(!dfs(i, 0)) {f = false;break;}}}if(f) cout << "Yes";else cout << "No";return 0;
}

好了这期分享就到这里了。

这里是我的全部分享

抱歉最近准备蓝桥杯青少组的比赛更新的比较慢(未来也会是这样)

大家谅解一下。

这期分享出的比较仓促也没有视频,非常抱歉。

这是作业,感谢@冷月无声re,差点忘了。

下期见!

(凑个整,250(wtcl))

这篇关于c++全套流水账——染色法判断二分图,DFS的实践与应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/351405

相关文章

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3