二分图的判定

二分图定义

如果一张无向图的 N N N个节点( N ≥ 2 N \geq 2 N2)可以分为 A , B A,B A,B两个非空集合,其中 A ∩ B = ∅ A\cap B=\empty AB=,并且任意同一集合内的点没有边相连,那么这张图为一张二分图

判定方法

一个图是二分图当且仅当图中不存在长度为奇数的环。

例题

关押罪犯
code

#include  

using namespace std; 

const int N = 2e4 + 100, M = 1e5 + 100; 

template <typename T> inline void read(T &s) {
	s = 0; T w = 1, ch = getchar();
	while(!isdigit(ch)) { if(ch == '-') w = -1; ch = getchar(); }
	while(isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
	s *= w;
}

int n, m, tot; 
int lin[N], vis[N]; 
bool flag; 
struct edge {
	int next, to, dis; 
}e[M<<1]; 

inline void add(int from, int to, int dis) {
	e[++tot].to = to; 
	e[tot].dis = dis; 
	e[tot].next = lin[from]; 
	lin[from] = tot; 
}

void dfs(int x, int color, int mid) {
	vis[x] = color; 
	for (int i = lin[x]; i; i = e[i].next) {
		int y = e[i].to; 
		if (e[i].dis <= mid) continue; 
		if (!vis[y]) dfs(y, 3-color, mid); 
		else if (vis[y] == color) {
			flag = false; 
			return ; 
		} 
	}
}

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

int main() {
	read(n), read(m); 
	int L = 0, R = 0; 
	for (int i = 1; i <= m; ++i) {
		int x, y, z; 
		read(x), read(y), read(z); 
		add(x, y, z); 
		add(y, x, z); 
		R = max(R, z); 
	}
	while (L < R) {
		int mid = (L + R) >> 1; 
		if (check(mid)) R = mid; 
		else L = mid + 1; 
	}
	printf("%d\n", L); 
	return 0; 
}

你可能感兴趣的:(图论——二分图,图论——图论,题解————题解)