You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

60 lines
2.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 20010, M = 200010;
int n, m;
int color[N]; // 二分图的标记数组
// 邻接表
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
// 是不是一个合法的二分图
// u:节点号 c:颜色12白 3-c互转, limit:最小冲突值
int dfs(int u, int c, int limit) {
color[u] = c; // 染色为c
for (int i = h[u]; ~i; i = ne[i]) { // 枚举每条出边
if (w[i] <= limit) continue; // 不关心小于limit冲突值的关系
// 如果没有被continue掉说明这条边i的冲突w[i]是大于两个监狱之间的最大冲突的,需要把这两个人放到不同的监狱里
int v = e[i];
if (color[v]) { // 如果v染过色
if (color[v] == c) return 0; // 并且与u一样那就冲突了
} else if (!dfs(v, 3 - c, limit)) // 如果没有染过色,并且在后续的染色过程中出现冲突,也就是无法成为合法二分图
return 0; // 染色失败
}
return 1; // 染色成功
}
// 使用limit做为最小的冲突值这样划分的两个图是不是二分图
int check(int limit) {
memset(color, 0, sizeof color); // 清空二分图的标记数组
for (int i = 1; i <= n; i++)
if (color[i] == 0) // 如果没有标记过,将i这个点标识为黑色:1
if (!dfs(i, 1, limit)) // 存在冲突,不是二分图,返回false
return 0;
return 1; // 没有冲突,是二分图
}
int main() {
scanf("%d %d", &n, &m);
memset(h, -1, sizeof h);
while (m--) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
add(a, b, c), add(b, a, c);
}
// 二分答案
int l = 0, r = 1e9;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
// 输出最小的匹配值
printf("%d\n", l);
return 0;
}