当前位置: 首页 > news >正文

C++二分图

二分图(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; // 初始颜色为0
        
        while (!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)。
  • 非连通图处理:需检查所有连通分量。
  • 奇数环判定:若存在奇数长度的环,则不是二分图。

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

相关文章:

  • Redis集群化方案对比:Codis、Twemproxy、Redis Cluster
  • Qt互斥锁(QMutex)的使用、QMutexLocker的使用
  • 基于单片机的GPS定位系统设计
  • 多线程经典案例
  • Vue3国际化开发实战:i18n-Ally + vue-i18n@next高效配置教程,项目中文显示
  • C 注释编写模版
  • redis的客户端连接的可视化管理工具
  • 基于 Ollama+Docker+OpenWebUI 的本地化部署deepseek流程
  • 高频 SQL 50 题(基础版)_626. 换座位
  • 6-2JVM解释器
  • 2025年企业网络安全实战指南:常见漏洞解析与全方位防御策略
  • 机器视觉Halcon支持这些协议或标准接口
  • 鸿蒙启动页开发
  • 对“预训练”的理解
  • 深入理解Spring @Async:异步编程的利器与实战指南
  • C++核心编程之STL
  • NLP09-拓展1-对比其他分类器(SVM)
  • Android SystemUI开发(一)
  • 【废物研究生零基础刷算法】DFS与递归(二)习题
  • Socket是什么接口
  • 马上评|安排见义勇为学生补考,善意与善意的双向奔赴
  • 陈吉宁龚正黄莉新胡文容等在警示教育基地参观学习,出席深入贯彻中央八项规定精神学习教育交流会
  • 国新办将就2025年4月份国民经济运行情况举行新闻发布会
  • 外交部:各方应为俄乌双方恢复直接对话创造条件
  • 国际能源署:全球电动汽车市场强劲增长,中国市场继续领跑
  • 微软将裁员3%,减少管理层