染色法判断无向图是否为二部图

本文介绍了二分图的概念,即一个图的顶点可以分割为两个互不相交的子集,每条边连接不同子集的顶点。通过染色法可以判断一个图是否为二分图,算法采用DFS遍历并交替染色,如果在染色过程中发现颜色冲突则不是二分图。提供的C++代码实现了这一算法,并给出了测试样例。时间复杂度为O(m+n)。
摘要由CSDN通过智能技术生成

二分图

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
二分图举例

图1 二分图举例

在这里插入图片描述

图2 非二分图举例

从上面的例子我们可以看到,二分图中的顶点可以分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。
我们可以对两个点集进行 **“染色”**从而进行区分,这也给了我们判断一个图是否为二分图的思路:

  • 遍历图中所有顶点,交替染色,如果在染色的过程中,发现一个顶点v的邻点w颜色与该顶点v相同,那么显然该图不是一个二分图。如果所有顶点都被成功的交替染色,那么最终可以判断原图G是二分图。

染色法代码

算法的代码如下(C++版本):

#define Max 10001
#define white 0 //white表示该顶点还未被遍历到,没有颜色
#define blue 1 //以red和blue作为染色的颜色
#define red 2
#include<iostream>
using namespace std;
int n, m;
int adj[Max][Max]; //邻接表
int color[Max]; //存储顶点颜色的数组
void Init() //初始化邻接矩阵和颜色数组
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			adj[i][j] = 0;

	for (int i = 0; i < n; i++)
		color[i] = white;
}
bool dyeing_judge(int s,int s_color) //染色法,用DFS对图进行遍历
{
	color[s] = s_color; //将顶点s先染成指定颜色
	for (int i = 0; i < n; i++)
	{
		if (adj[s][i] != 0) { //对于s相邻的每个顶点v
			if (color[i] == s_color) //如果v已经在之前的遍历染成相同的颜色
				return false; //说明原图不是二部图,返回false
			else if (color[i] == white) { //如果v没有被染色
				int c = color[s] == blue ? red : blue; //交替指定颜色
				return dyeing_judge(i, c); //DFS遍历v
			}	
		}
	}
	return true; //所有顶点染色成功,返回true
}
int main()
{
	cin >> n >> m; //输入顶点、边的数量
	int s, t;
	Init(); //初始化
	for (int i = 0; i < m; i++) {//依次输入边
		cin >> s >> t;
		adj[s-1][t-1] = 1;
		adj[t-1][s-1] = 1;
	}
	bool judge = dyeing_judge(0, red);
	//输出判断:是否是二分图
	if (judge)cout << "yes" << endl;
	else cout << "no" << endl;
}

测试样例

输入:

3 3
1 2
2 3
1 3

输出:

no

输入:

2 1
1 2

输出:

yes

时间复杂度分析

初始化的复杂度为 O ( n ) O(n) O(n),染色DFS遍历的时间复杂度为 O ( m + n ) O(m+n) O(m+n)
算法的总时间复杂度为 O ( m + n ) O(m+n) O(m+n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值