行业知识
图论 - 二分图(染色法、匈牙利算法)
2026-11-02 00:38:14
来源:互联网转载
文章目录
- 前言
- Part 1:染色法判定二分图
- 1.题目描述
- 输入格式
- 输出格式
- 数据范围
- 输入样例
- 输出样例
- 2.算法
- Part 2:匈牙利算法求二分图的最大匹配
- 1.题目描述
- 输入格式
- 输出格式
- 数据范围
- 输入样例
- 输出样例
- 2.���法
前言
本篇博客将介绍两种二分图有关的算法,分别是染色法判定二分图和匈牙利算法求二分图的最大匹配。那么我们先要知道什么是二分图?
二分图:有两顶点集且图中每条边的的两个顶点分别位于两个顶点集中,每个顶点集中没有边直接相连接。也就是:图中点通过移动能分成左右两部分,左侧的点只和右侧的点相连,右侧的点只和左侧的点相连。如下图:
Part 1:染色法判定二分图
1.题目描述
给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环。
请你判断这个图是否是二分图。
输入格式
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 u 和 v,表示点 u 和点 v 之间存在一条边。
输出格式
如果给定图是二分图,则输出 Yes,否则输出 No。
数据范围
1≤n,m≤105
输入样例
4 41 31 42 32 4
输出样例
Yes
2.算法
- 开始对任意一未染色的顶点染色
- 判断其相邻的顶点中,若未染色则将其染上和相邻顶点不同的颜色(因为二分为两个顶点集合,所以一共两种颜色,分别用1和2代替)
- 若已经染色且颜色和相邻顶点的颜色相同则说明不是二分图,若颜色不同则继续判断
- 用DFS即可
#include #include #include using namespace std;const int N = 100010 * 2;int e[N], ne[N], idx;//邻接表存储图int h[N];int color[N];//保存各个点的颜色,0 未染色,1 是红色,2 是黑色int n, m;//点和边void add(int a, int b)//邻接表插入点和边{ e[idx] = b, ne[idx]= h[a], h[a] = idx++;}bool dfs(int u, int c)//深度优先遍历{ color[u] = c;//u的点成 c 染色 //遍历和 u 相邻的点 for(int i = h[u]; i!= -1; i = ne[i]) { int b = e[i]; if(!color[b])//相邻的点没有颜色,则递归处理这个相邻点 { if(!dfs(b, 3 - c)) return false;//(3 - 1 = 2, 如果 u 的颜色是2,则和 u 相邻的染成 1) //(3 - 2 = 1, 如果 u 的颜色是1,则和 u 相邻的染成 2) } else if(color[b] && color[b] != 3 - c)//如果已经染色,判断颜色是否为 3 - c { return false;//如果不是,说明冲突,返回 } } return true;}int main(){ memset(h, -1, sizeof h);//初始化邻接表 cin >> n >> m; for(int i = 1; i > a >> b; add(a, b), add(b, a); } for(int i = 1; i > m; // 保存图,因为只从一遍找另一边,所以该无向图只需要存储一个方向 for(int i = 0; i > a >> b; add(a, b); } int res = 0; //为各个点找匹配 for(int i = 1; i
上一篇:我的服务器怎么创造?
下一篇:连接云服务器怎么购买?