二分图定义
如果一张无向图的 N N N个节点( N ≥ 2 N \geq 2 N≥2)可以分为 A , B A,B A,B两个非空集合,其中 A ∩ B = ∅ A\cap B=\empty A∩B=∅,并且任意同一集合内的点没有边相连,那么这张图为一张二分图
判定方法
一个图是二分图当且仅当图中不存在长度为奇数的环。
例题
关押罪犯
code
#include <bits/stdc++.h>
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;
}