信奥赛C++提高组csp-s之二分图

一、什么是二分图
二分图:一个图的所有顶点可以分成两个不相交的集合U和V,使得图中每条边都连接一个U中的顶点和一个V中的顶点。也就是说,图中不存在连接同一集合内顶点的边。
二、判定方法:染色法
核心思想:用两种颜色给图中的顶点染色,相邻顶点颜色不同。如果能成功完成染色,则是二分图;否则不是。
算法步骤:
- 从任意一个未染色的顶点开始,染成颜色1
- 将其相邻顶点染成颜色2
- 对相邻顶点递归染色
- 如果发现相邻顶点颜色相同,则不是二分图
三、研究案例:简单二分图判定
题目描述:给定一个无向图,判断它是否是二分图。
输入格式:
- 第一行:n m(n个顶点,m条边)
- 接下来m行:每行两个整数u v,表示一条边
输出格式:是二分图输出"Yes",否则输出"No"
输入样例1:
5 4
1 2
2 3
3 4
4 5
输出样例1:
Yes
输入样例2:
3 3
1 2
2 3
1 3
输出样例2:
No
代码实现:
cpp
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005; // 最大顶点数
vector<int> graph[MAXN]; // 邻接表存储图
int color[MAXN]; // 记录每个顶点的颜色:0未染色,1红色,2蓝色
bool f; // 是否是二分图
// DFS染色函数
void dfs(int node, int c) {
color[node] = c; // 给当前顶点染色
// 遍历所有相邻顶点
for (int i = 0; i < graph[node].size(); i++) {
int neighbor = graph[node][i];
// 如果相邻顶点未染色,染成相反颜色
if (color[neighbor] == 0) {
dfs(neighbor, 3 - c); // 3-c实现颜色交替:1→2,2→1
}
// 如果相邻顶点颜色相同,不是二分图
else if (color[neighbor] == c) {
f = false;
return;
}
}
}
int main() {
int n, m;
cin >> n >> m;
// 读取边,构建邻接表
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u); // 无向图,双向添加
}
// 初始化
memset(color, 0, sizeof(color));
f = true;
// 遍历所有顶点(处理非连通图的情况)
for (int i = 1; i <= n; i++) {
if (color[i] == 0) { // 顶点未染色
dfs(i, 1); // 从该顶点开始染色
}
if (!f) break; // 发现不是二分图,提前结束
}
// 输出结果
if (f) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
四、算法分析
时间复杂度:
- O(n + m),其中n是顶点数,m是边数
空间复杂度:
- O(n + m),用于存储图和颜色信息
五、注意事项
- 图可能不连通:需要遍历所有顶点进行染色
- 自环和重边:二分图不能有自环(顶点连接自己)
- 染色冲突检测:发现冲突立即返回,提高效率
- 二分答案边界:注意左边界和右边界的初始值
各种学习资料,助力大家一站式学习和提升!!!
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<"########## 一站式掌握信奥赛知识! ##########";
cout<<"############# 冲刺信奥赛拿奖! #############";
cout<<"###### 课程购买后永久学习,不受限制! ######";
return 0;
}
- 一、CSP信奥赛C++通关学习视频课:
- C++语法基础
- C++语法进阶
- C++算法
- C++数据结构
- CSP信奥赛数学
- CSP信奥赛STL
- 二、CSP信奥赛C++竞赛拿奖视频课:
- 信奥赛csp-j初赛高频考点解析
- CSP信奥赛C++复赛集训课(12大高频考点专题集训)
- 三、csp高频考点知识详解及案例实践:
- CSP信奥赛C++之动态规划
- CSP信奥赛C++之标准模板库STL
- 信奥赛C++提高组csp-s知识详解及案例实践
- 四、考级、竞赛刷题题单及题解:
- GESP C++考级真题题解
- CSP信奥赛C++初赛及复赛高频考点真题解析
- CSP信奥赛C++一等奖通关刷题题单及题解
详细内容:
1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):
https://edu.csdn.net/lecturer/7901 点击跳转



2、CSP信奥赛C++竞赛拿奖视频课:
https://edu.csdn.net/course/detail/40437 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:
CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转
CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转
信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html
4、csp信奥赛冲刺一等奖有效刷题题解:
CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转
CSP信奥赛C++一等奖通关刷题题单及题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转
5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转
· 文末祝福 ·
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<"跟着王老师一起学习信奥赛C++";
cout<<" 成就更好的自己! ";
cout<<" csp信奥赛一等奖属于你! ";
return 0;
}