关于二分图

二分图,又称为二部图、偶图,是一种重要的图模型

二分图判定

下面给出二分图的定义:
给定无向图G = < V,E >,如果可以将结点集V划分成两个子集V1和V2,使得边集E中的任何一条边,一个结点在V1中,另一个在V2中
具备这样性质的图,称为二分图
其中V1和V2称为结点互补集
通常将二分图记为G = < V1,E,V2 >
如果V1 中的每个结点和V2 中的每个结点之间都有边,则称 G = < V1,E,V2 > 为完全二分图

根据二分图的定义,可以得到平凡图和零图都是二分图。同时,由于没有一条边的两个结点同属于V1 或V2 ,因此在二分图中,没有自回路

在这里插入图片描述
判断一个图是否为二分图的关键在于能否将图的结点集划分为两个结点集,其中两个结点集之间没有边存在

在这里插入图片描述
我们把v1放在一个结点集中,与他有边的结点v4,v6,v7,v8应当属于另一个结点集,但是结点v6和v7之间有边,不符合二分图的定义,所以a图不是二分图
同理b图,把v1放在一个结点集中,与他有边的结点v2,v3,v4属于另一个结点集,看v5,v5与v1在一个结点集,其他与他有边的点属于另一个结点集,符合二分图的定义,所以b图是二分图

判定定理
设 G = < V, E > 是无向图,则该图是二分图,当且仅当 G 中所有的回路长度是偶数

我们还可以用图的着色来判断二分图
如果一个无向图只能被两种颜色着上,他的着色数是2的话,那么这个图就是二分图

vector<int>G[1001];
int T,n,m,col[1001];

int dfs(int u,int c)
{
	if(col[u] == 0) col[u] = c;
	for(auto v : G[u]){
		if(col[v] == c) return 0;
		if(col[v] == 0 && dfs(v,-c) == 0) return 0;
	}
	return 1;
}

void Solve(){
	for(int i=1;i<=n;i++){
		if(col[i] == 0){
			if(dfs(i,1) == 0){
				printf("No\n");
				return;
			}
		}
	}
	printf("Yes\n");
}

int main(){
	
	scanf("%d",&T);
	while(T--){

		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++){
			col[i] = 0;
			G[i].clear();
		}
		for(int i=0;i<m;i++){
			int u,v;
			scanf("%d%d",&u,&v);
			G[u].push_back(v);
			G[v].push_back(u);
		}
		Solve();
	}	
	return 0;
}

二分图匹配

给出二分图匹配的定义:
设G = < X, E,Y > 是二分图,X 和 Y 是互补结点子集。若存在 E 的子集 M ,使 M 中的边没有共同结点,称 M 为图 G 的一个匹配。
G 中与 M 中的边相关联的结点称为匹配 M 的饱和结点,其他结点称为非饱和结点。
如果 X 中每个结点都是匹配 M 的饱和结点,则称 M 为 G 的一个 X -完全匹配;如果Y 中每个结点都是匹配 M 的饱和结点,则称 M 为 G 的一个Y -完全匹配
如果 M 既是 X -完全匹配,又是Y -完全匹配,称该匹配为 G 的完全匹配
G 中基数最大的匹配称为 G 的最大匹配,最大匹配中边的数量称为 G 的匹配数

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

你数过天上的星星吗

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

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

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

打赏作者

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

抵扣说明:

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

余额充值