二分图的学习

前言

在图论里,二分图是一类结构非常特殊、应用极广的无向图。本文用通俗语言讲清什么是二分图、性质、判定方法,最后给出一份简洁可直接使用的 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. 部分网络流问题可转化为二分图模型求解
相关推荐
遇印记6 小时前
传输层,网络层
运维·服务器·网络·windows·学习
clorinda7 小时前
PyQt5学习:从界面搭建到与机器学习实战
学习
欣欣之王来了9 小时前
Vue3项目脚手架:Vite vs Vue CLI怎么选?
前端·学习·架构·项目·vue3教程
kaixin_啊啊9 小时前
【零基础学AI】第 7 章——让 AI 辅助学习和办公
人工智能·学习
信奥卷王9 小时前
[GESP202506 六级] 学习小组(含视频)
学习
宛 禾10 小时前
Qt 控件入门:QLabel 从拖拽到对象树,一篇讲透
c++·qt·学习
无敌贵点大王11 小时前
嵌入式软件面试经(自用)
c语言·stm32·单片机·学习·mongodb·面试·职场和发展
Xudde.11 小时前
PwnLab: init 靶机渗透测试(Vulnhub Writeup)
笔记·学习·安全·web安全
我命由我1234511 小时前
Function Calling 模型
人工智能·python·学习·ai·学习方法·ai编程·ai写作
别动我齐刘海12 小时前
实时控制学习2
linux·c++·人工智能·学习·算法