二分图判定

定义

对于二分图,就个人理解,是一种可以将顶点划分成两个集合的无向图,和顶点连接的边每一条都连接着这两个集合,也就是说判定一个二分图就看这张图的任意边连接的两个顶点能不能归属于两个集合。有一个等价定义是:不含有「含奇数条边的环」的图。
以下举一个非二分图的例子:(显然这张图含有奇数条边的环)
在这里插入图片描述
无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。


概念

  1. 什么是匹配
    匹配是一个集合的概念,这个集合包含多条边,并且这多条边没有公共的顶点。也就是说一个匹配集中有 n n n条边就对应着 2 ∗ n 2*n 2n个不同的顶点。(但是显然匹配并不一定包含着全部可匹配的点,所有匹配的极大集也就是最大匹配)。
  2. 什么是最大匹配?
    一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。
  3. 什么是完美匹配?
    一个图的某个匹配中,恰好包含所有顶点,也就是说所有点都是匹配点则称这是完美匹配。就是每个点都能够有唯一映射。
  4. 交替路是什么?
    顾名思义,一种依次交替经过非匹配边、匹配边的路径。
  5. 增广路是什么?
    顾名思义,增广,扩充的含义,实际上是扩充匹配集,即新加进来一个匹配边,两个匹配点。从未匹配点走交替路,来到另一个未匹配点,则称增广路。
增广路有一个重要特点:非匹配边比匹配边多一条。因此,研究增广路的意义是改进匹配。只要把增广路中的匹配边和非匹配边的身份交换即可。由于中间的匹配节点不存在其他相连的匹配边,所以这样做不会破坏匹配的性质。交换后,图中的匹配边数目比原来多了 1 条。其实,如果交替路以非匹配点结束的,那么这条交替路就是一条增广路,我们可以通过不停地找增广路来增加匹配中的匹配边和匹配点。找不到增广路时,达到最大匹配(这是增广路定理)。匈牙利算法正是这么做的

参考出处


判定

染色法,可以用深搜或者广搜来解决。核心思路是找一个点,染A色后对其邻点都染B色,如果某个邻点已经染色并且和它一样,则不是二分图,否则和它不一样就不用考虑它。

Code

int color[maxnn]; //每个点的颜色
int n; //n个点
int head[maxnn], son[maxnm], nxt[maxnm], cnt; //链式前向星

//把当前的点cur染成颜色c
bool dfs(int cur, int c) {
	color[cur] = c;
	for (int i = head[cur]; ~i; i=nxt[i]) {
		int v = son[i];
		if (color[v] == c) return false; //发现邻居有已被染色并且和它一样显然不是二分图
		if (!color[v] && !dfs(v, -c)) return false; //没被染色,染后发现这条搜索路径会不符合二分图
	}
	return true; //所有顶点都符合二分图的判定
}

bool solve() {
	for (int i = 1; i <= n; i++)
		if (!color[i] && !dfs(i, 1)) return false; //i点还没染色进去i所在的环判定
	return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胡同的诗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值