二分图的学习

前言

在图论里,二分图是一类结构非常特殊、应用极广的无向图。本文用通俗语言讲清什么是二分图、性质、判定方法,最后给出一份简洁可直接使用的 C++ 二分图判定代码。

一、什么是二分图

1. 定义

给定一个无向图,如果可以把图中所有顶点划分成两个互不相交的集合 {U,V},满足:

  1. 所有边的两个端点,一定一个在 U、一个在 V;
  2. 同一个集合内部的点之间没有边相连

满足这个条件的图,就叫做二分图(二部图)

形象理解: 把点分成左右两堆,所有边只能跨左右连,同一边内部不能有边。

2. 等价重要性质(核心)

一个无向图是二分图,当且仅当图中不存在长度为奇数的环(奇环)。

  • 有奇环 → 一定不是二分图
  • 没有奇环 → 一定是二分图

例子:

  • 三角形(3 个点两两相连,环长 3,奇数)→ 不是二分图
  • 一条链、四边形、树(树没有任何环)→ 都是二分图

3. 特殊情况

  • 孤立点(没有任何边的点):可以随便分到任意一侧,不影响二分图性质;
  • 树:所有树都是二分图(无环,自然无奇环)。

二、二分图的判定思路:染色法

思想

尝试用两种颜色给图中每个点染色,要求:

  • 相邻的两个点颜色必须不同;
  • 若染色过程中发现:一个点和已经染色的邻居颜色相同 → 存在奇环,不是二分图。

实现方式常用:DFS / BFS BFS 更安全,不会出现递归深度过大栈溢出的问题。

三、C++ 完整实现

功能:输入无向图,判断是否为二分图,输出结果。

使用说明

  1. 第一行输入点数 n、边数 m;
  2. 接下来 m 行每行输入两个点 \(u,v\),代表无向边;
  3. 程序自动遍历所有连通块,判断是否为二分图并输出。
cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

const int MAXN = 100005;
vector<int> g[MAXN];
// -1未染色,0和1代表两种颜色
int color[MAXN];
int n, m;
bool ok = true;

void bfs(int s) {
    queue<int> q;
    q.push(s);
    color[s] = 0;
    while (!q.empty() && ok) {
        int u = q.front();
        q.pop();
        for (int v : g[u]) {
            if (color[v] == -1) {
                color[v] = color[u] ^ 1;
                q.push(v);
            } else if (color[v] == color[u]) {
                ok = false;
                return;
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    memset(color, -1, sizeof color);
    for (int i = 1; i <= m; ++i) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for (int i = 1; i <= n && ok; ++i) {
        if (color[i] == -1) {
            bfs(i);
        }
    }
    if (ok) cout << "Yes, it is a bipartite graph\n";
    else cout << "No, not a bipartite graph\n";
    return 0;
}

四、简单复杂度说明

每个点、每条边只会被访问一次,时间复杂度 \(O(n+m)\),可以处理较大范围的图。

五、拓展:二分图能干嘛?

判定只是基础,二分图常见经典问题:

  1. 二分图最大匹配(匈牙利算法)
  2. 最大独立集、最小顶点覆盖(二分图有对应定理)
  3. 部分网络流问题可转化为二分图模型求解
相关推荐
小O的算法实验室2 小时前
IEEE TII,学习为多目标深度学习生成偏好
人工智能·深度学习·学习
吃好睡好便好3 小时前
说说高温对情绪的影响
学习·生活·情绪·高温
for_ever_love__3 小时前
python基础语法学习: 文件操作
python·学习
m4Rk_4 小时前
【论文阅读】Agent 记忆机制(38):AMA——用多智能体协作动态选择记忆粒度
论文阅读·人工智能·学习
zjnlswd5 小时前
c# 刘铁猛 学习笔记
笔记·学习
LuminousCPP5 小时前
单链表专题(三)-刷题复盘篇:从快慢指针到环形链表 II 数学推导
数据结构·经验分享·笔记·学习·算法·链表
你想知道什么?6 小时前
朴素贝叶斯算法-学习笔记
笔记·学习·算法
天吾cc6 小时前
JSON 与 cJSON 学习笔记
笔记·学习·json
lifallen6 小时前
Orca 与 Emdash:同样管理多个 Agent,差别在谁来调度
人工智能·学习·ai·软件构建·开源软件·ai编程
runafterhit6 小时前
【学习地图】ARM嵌入式类 · 文章索引
arm开发·学习