判断无向连通图是二分图的方法(黑白染色法)

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

黑白染色法判断无向连通图是二分图的大致思路就是先找到一个没被染色的节点u,把它染上一种颜色,之后遍历所有与它相连的节点v,如果节点v已被染色并且颜色和节点u一样,那么就失败了。如果这个节点v没有被染色,先把它染成与节点u不同颜色的颜色,然后遍历所有与节点v相连的节点......。就这样循环下去,直到结束为止。

注意:若图G是非连通图,则需要依次判断各连通子图是不是二分图。

【程序代码】

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;

vector<int> G[maxn];
int color[maxn];

int bfs(int u) {
	queue<int> Q;
	Q.push(u);
	color[u]=1;

	while(!Q.empty()) {
		int t=Q.front();
		Q.pop();
		for(int i=0; i<G[t].size(); i++) {
			if(color[G[t][i]]==color[t])
				return 0; //Adjacent nodes are the same color, not bipartite graph
			else if(color[G[t][i]]==0) { //no dyeing
				color[G[t][i]]=-color[t];
				Q.push(G[t][i]);
			}
		}
	}

	return 1;
}

int main() {
	int n,m,x,y;
	cin>>n>>m;

	for(int i=0; i<n; i++) { //init
		G[i].clear();
		color[i]=0;
	}

	for(int i=0; i<m; i++) { //Adjacency List
		cin>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}

	if(bfs(1))
		cout<<"YES"<<endl;
	else
		cout<<"NO"<<endl;

	return 0;
}


【测试数据】

in1:
9 8
1 6
2 6
2 7
3 8
3 9
4 7
5 6
5 9

out1:
YES
----------

in2:
9 8
1 6
2 6
2 7
3 8
3 9
4 7
5 6
6 7

out2:
NO



【参考文献】
https://baike.baidu.com/item/%E4%BA%8C%E5%88%86%E5%9B%BE/9089095?fr=aladdin
https://www.cnblogs.com/jsawz/p/6847185.html
https://blog.csdn.net/qq_43469254/article/details/88956159
https://blog.csdn.net/chaiwenjun000/article/details/47662911
https://blog.csdn.net/l2533636371/article/details/79749020
https://blog.csdn.net/FeBr2/article/details/51932611

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值