C++二分图

ops/2025/3/4 0:17:23/

二分图(Bipartite Graph)是一种特殊的图结构,其顶点可以分成两个互不相交的集合,使得每条边的两个顶点分别属于这两个集合。二分图在匹配问题(如任务分配、婚姻匹配)和网络流算法中有重要应用。


核心概念

  • 定义:图 ( G = (V, E) ) 的顶点集 ( V ) 可划分为两个不相交的子集 ( U ) 和 ( V ),使得每条边的两个端点分别属于 ( U ) 和 ( V )。
  • 特性
    • 图中不包含奇数长度的环
    • 可以用颜色标记法(如红蓝染色)验证是否为二分图。

检测二分图的算法

通过颜色标记法(DFS/BFS遍历染色)判断图是否满足二分性:

算法步骤
  1. 选择一个起始顶点,标记为颜色1(如红色)。
  2. 遍历其所有相邻顶点,标记为颜色2(如蓝色)。
  3. 递归或迭代处理相邻顶点,若发现相邻顶点颜色冲突(相同颜色),则图不是二分图。
  4. 对所有未访问的连通分量重复此过程。

C++ 模板代码(基于邻接表的DFS实现)

#include <vector>
#include <queue> // 若用BFS需包含此头文件using namespace std;class Solution {
public:bool isBipartite(vector<vector<int>>& graph) {int n = graph.size();vector<int> color(n, -1); // -1表示未染色,0和1表示两种颜色for (int i = 0; i < n; i++) {if (color[i] == -1) { // 处理每个连通分量if (!dfs(graph, color, i, 0)) return false;// 若用BFS:if (!bfs(graph, color, i)) return false;}}return true;}private:// DFS实现bool dfs(vector<vector<int>>& graph, vector<int>& color, int node, int current_color) {if (color[node] != -1) {return color[node] == current_color; // 检查颜色是否冲突}color[node] = current_color;for (int neighbor : graph[node]) {if (!dfs(graph, color, neighbor, 1 - current_color)) return false;}return true;}// BFS实现bool bfs(vector<vector<int>>& graph, vector<int>& color, int start) {queue<int> q;q.push(start);color[start] = 0; // 初始颜色为0while (!q.empty()) {int node = q.front();q.pop();for (int neighbor : graph[node]) {if (color[neighbor] == -1) { // 未染色color[neighbor] = 1 - color[node]; // 染相反颜色q.push(neighbor);} else if (color[neighbor] == color[node]) { // 颜色冲突return false;}}}return true;}
};

代码解释

  • 邻接表graph 是邻接表形式,graph[i] 表示顶点 i 的邻居列表。
  • 颜色数组color 记录每个顶点的颜色(-1未染色,0和1为两种颜色)。
  • DFS/BFS
    • DFS递归染色,若发现相邻顶点颜色相同则返回 false
    • BFS通过队列逐层染色,遇到冲突立即终止。

应用场景

  1. 匹配问题:如匈牙利算法求二分图的最大匹配。
  2. 任务调度:将任务和资源分为两组,边表示可分配关系。
  3. 广告推荐:用户和广告分为两组,边表示用户对广告的兴趣。

关键点总结

  • 时间复杂度:O(V + E),每个顶点和边被访问一次。
  • 空间复杂度:O(V),用于存储颜色和递归栈(DFS)或队列(BFS)。
  • 非连通图处理:需检查所有连通分量。
  • 奇数环判定:若存在奇数长度的环,则不是二分图。

通过颜色标记法,可以高效判断图是否为二分图,并进一步用于解决更复杂的匹配和分配问题。


http://www.ppmy.cn/ops/162908.html

相关文章

《机器学习数学基础》补充资料:可逆矩阵的手工计算方法和总结

《机器学习数学基础》第2章2.3.1节阐述了可逆矩阵的定义、性质&#xff0c;并演示了Python中的计算函数及其应用。 本文是对书中这部分内容的补充&#xff0c;主要是说明如何用手工计算的方法得到常用矩阵的逆矩阵&#xff08;如果可逆&#xff09;。 若一个矩阵存在逆矩阵&am…

spring注解开发(Spring整合JUnit+MyBatis)(7)

目录 一、项目环境初始化。 &#xff08;1&#xff09;数据库与数据表。 &#xff08;2&#xff09;pom文件中的核心依赖坐标。 &#xff08;3&#xff09;实体类。 &#xff08;4&#xff09;service层。 &#xff08;5&#xff09;dao层。&#xff08;Mapper代理模式&#xf…

Android Binder 用法详解

Binder 是 Android 系统中的一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;它允许不同进程之间进行高效通信。Binder 在 Android 系统中被广泛使用&#xff0c;例如在 Activity 与 Service 的交互中。 Binder 的基本组成 实现 Binder 通信通常包含以下几个关键部…

如何在netlify一键部署静态网站

1. 准备你的项目 确保你的静态网站文件&#xff08;如 HTML、CSS、JavaScript、图片等&#xff09;都在一个文件夹中。通常&#xff0c;项目结构如下&#xff1a; my-static-site/ ├── index.html ├── styles/ │ └── styles.css └── scripts/└── script.js…

分类预测 | Matlab实现GWO-LSSVM灰狼算法优化最小二乘支持向量机多特征分类预测

分类预测 | Matlab实现GWO-LSSVM灰狼算法优化最小二乘支持向量机多特征分类预测 目录 分类预测 | Matlab实现GWO-LSSVM灰狼算法优化最小二乘支持向量机多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现GWO-LSSVM灰狼算法优化最小二乘支持向量机…

矩阵的奇异值(SVD)分解和线性变换

矩阵的奇异值&#xff08;SVD&#xff09;分解和线性变换 SVD定义 奇异值分解&#xff08;Singular Value Decomposition&#xff0c;简称 SVD&#xff09;是一种重要的线性代数工具&#xff0c;能够将任意矩阵 ( A ∈ R m n \mathbf{A} \in \mathbb{R}^{m \times n} A∈Rmn…

ubuntu中ollama设置记录

自己同一台电脑主机安装3080和3090显卡&#xff0c;测试发现ollama只默认跑在3090上&#xff1b;故查看一下设置&#xff0c;成功也把3080也运行起来了。 原因如下&#xff1a; 开始设置记录&#xff1a; Environment Variables: OLLAMA_DEBUG 作用&#xff1a;显示额外的调试…

【R语言】PCA主成分分析

使用R语言手动实现PCA主成分分析计算&#xff0c;通过计算协方差矩阵计算出数据的主成分得分&#xff0c;根据的分最高的特征进行得分图的绘制 # 读取数据raw_data <- read.csv("R可视化/data.csv", header TRUE, fileEncoding "GBK")new_data <-…