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.

76 lines
2.3 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;
typedef pair<int, int> PII;
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++;
}
// bfs实现
int bfs(int u, int limit) {
// 假设 1:黑2这样方便理解一些
color[u] = 1;
queue<PII> q; // 两个属性:节点号,颜色
q.push({u, 1}); // 将节点u入队列,颜色为黑
while (q.size()) {
PII t = q.front();
q.pop();
int u = t.first, c = t.second;
// 找到这个节点关联的其它节点
for (int i = h[u]; ~i; i = ne[i]) {
if (w[i] <= limit) continue; // 不关心小于limit冲突值的关系
int v = e[i];
// 没染色就染成相反的颜色
if (!color[v]) {
color[v] = 3 - c;
// 并且把这个新的节点入队列,再探索其它的相邻节点
q.push({v, 3 - c});
} else if (color[v] == c)
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 (!bfs(i, 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;
}