二分图(仅二分图基础讲解)

闲的无聊来写个二分图的讲解吧。

读者可能会疑惑,二分图?什么叫做二分图,是由二分思想演变的图吗?

但是,二分图各位都见过,只是不知道它叫二分图。以下开始二分图的讲解

二分图:

大家小学肯定做过单词连线吧?(oh,小时候最让我头疼的东西了.. .0_._0.)

二分图(仅二分图基础讲解)_第1张图片

(原谅本蒟蒻英语不好...其实也不想写watermelon。。。) 

没错!这就是二分图的原型!为什么说这是二分图的原型呢?大家请看二分图的定义就知道了。

二分图定义:

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

这定义没人讲解,萌新看了谁不迷糊啊?

咳咳,换句人话说就是:我们把上面图中,单词部分记为A部分,翻译部分记为B部分。我们可以知道,A和B部分的各个点(单词)没有相互连接的情况,A部分中的点是连向B部分中的点,再次解释一下这句话的意思,A中的某一个点,可以连向B中任意多个点,但是A,B各个部分中的点是没有相互连接的。于是,我们就可以得到一个常规的二分图

 

二分图(仅二分图基础讲解)_第2张图片

到这里呢,我相信各位读者都以及明白了二分图是什么了,但是还有一个问题:如何判断一个图是二分图?

这里介绍一种常规的思想:染色法

二分图(仅二分图基础讲解)_第3张图片

我们选取A或者B部分中任意一个点进行染色:这里我们从A1开始进行染色

说明:因为二分图中,点与点的连线是没有方向的,如果一个图是二分图,那么这个图的每个点都是可以通过边到达的。也就是说,这里可以用DFS来进行染色

我们把A部分的所有点染为数字1,B部分的所有点染为数字2。如果最后A中所有点都染为了1,B中所有点都染为了2,那么就说明该图是二分图啦!

废话不多说,直接上代码:

例题链接:http://oj.daimayuan.top/course/14/problem/797

二分图(仅二分图基础讲解)_第4张图片

#include
using namespace std;
const int N = 1001;
vectore[N];//用于存图
int n, m, c[N];//c数组用于染色

bool dfs(int x) {
	for (auto y : e[x])
		if (!c[y]) {
			c[y] = 3 - c[x];
			if (!dfs(y))
				return false;
		}
		else if (c[x] == c[y])
			return false;

	return true;
}

bool check() {
	memset(c, 0, sizeof(c));
	for (int i = 1; i <= n; i++)
		if (!c[i]) {
			c[i] = 1;
			if (!dfs(i)) {
				return false;
			}
		}
	return true;
}

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; i++)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		e[x].push_back(y);
		e[y].push_back(x);
	}
	if (check()) printf("Yes\n");
	else printf("No\n");
}

 

 

 

你可能感兴趣的:(算法,算法)