二分图的学习

前言

在图论里,二分图是一类结构非常特殊、应用极广的无向图。本文用通俗语言讲清什么是二分图、性质、判定方法,最后给出一份简洁可直接使用的 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. 部分网络流问题可转化为二分图模型求解
相关推荐
Turbo正则1 小时前
群论学习入门 | 群论与李群的基本概念
人工智能·学习·算法·抽象代数
毛丫讲绘本1 小时前
0-3岁选绘本需要做到越早启蒙越要简单
人工智能·学习·微信·微信公众平台·微信开放平台
小c君tt1 小时前
linux学习笔记1
linux·笔记·学习
吃好睡好便好2 小时前
泰戈尔的诗歌6
学习·生活
双吉堡2 小时前
北京通州有哪些热门且专业的学画画画室?
学习
Go-higher3 小时前
DriverTest 驾考知识卡片学习助手 —— 一款基于 Jetpack Compose 的现代 Android 学习APP
android·学习
星幻元宇VR3 小时前
公共安全主题展厅设备【防洪防汛安全科普系统】
科技·学习·安全
AI科技星4 小时前
32维超复数流形中意识信息场与物质耦合的拓扑动力学
人工智能·学习·算法·数据挖掘·回归·乖乖数学·全域数学
鱼很腾apoc4 小时前
【Linux】第7期 进程间通信 (IPC) 详解:管道 (匿名 / 命名) + System V
linux·服务器·c语言·学习·进程间通信·ipc
科技大视界5 小时前
大学生专业课笔记本用哪款?来酷Air14酷睿版14英寸轻薄笔记本电脑适合学习任务多的人
学习