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

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

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

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

二分图:

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

(原谅本蒟蒻英语不好...其实也不想写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各个部分中的点是没有相互连接的。于是,我们就可以得到一个常规的二分图

 

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

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

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

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

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

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

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

#include<bits/stdc++.h>
using namespace std;
const int N = 1001;
vector<int>e[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");
}

 

 

 

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值