二分图的学习

前言

在图论里,二分图是一类结构非常特殊、应用极广的无向图。本文用通俗语言讲清什么是二分图、性质、判定方法,最后给出一份简洁可直接使用的 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. 部分网络流问题可转化为二分图模型求解
相关推荐
问天_观心23 分钟前
大模型微调学习(一)
开发语言·人工智能·学习·语言模型·github
苏生Susheng1 小时前
【软件实施】Linux系统Shell脚本教程
linux·运维·服务器·chrome·spring boot·学习·实施
我命由我123451 小时前
Photoshop - Photoshop 把两个 PSD 文件合并
学习·ui·职场和发展·产品运营·产品经理·学习方法·photoshop
小雪崩3 小时前
嵌入式学习 day39:TCP并发服务器模型
linux·服务器·c语言·网络·学习·tcp/ip
知识分享小能手4 小时前
深度学习学习教程,从入门到精通,概率与信息论 — 知识点详解(3)
人工智能·深度学习·学习·数据挖掘·概率论
Wendy不吃榴莲4 小时前
# AI短剧教程 - 《后西游记》开播后,AI影视为什么更考验“连续讲故事”?
人工智能·笔记·学习·ai·视频
Agudamu11614 小时前
B站学习视频怎么变笔记:用 Ai好记 + Obsidian 搭建个人知识库的完整教程
人工智能·笔记·学习·音视频
kkkkkkkkkk_Z4 小时前
学嵌入式和Linux应用编程|学习日记:计算机网络基础
linux·学习·计算机网络
麦田里的粮仓4 小时前
图形设计工具箱(免费开源)
学习
每天题库4 小时前
交安C证报考条件有哪些?公路水运安全员C证报名时间及考试科目
学习·安全·考试·题库·考证