题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1196


 

看起来和免费道路那道题是有共同点的,但细细一想,其实二者并不一样。免费道路要求恰好有k条鹅卵石路,而本题要求至少k条一级道路。

本题是想让边权最大的边最小(别去想最小生成树的性质!!!),所以可以二分答案,因为必然最大边权越大越容易满足,任意一条边都可以成为一级道路。

我们毕竟是要验证答案,所以应该先加一遍一级道路,然后再去补二级道路,这样才能够保证符合条件的不被判断为不符合条件。

 1 #include <cstdio>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 inline int get_num() {
 7     int num = 0;
 8     char c = getchar();
 9     while (c < '0' || c > '9') c = getchar();
10     while (c >= '0' && c <= '9')
11         num = num * 10 + c - '0', c = getchar();
12     return num;
13 }
14 
15 const int maxn = 1e4 + 5, maxm = 2e4 + 5;
16 
17 struct Edge {
18     int u, v, w1, w2;
19 } edge[maxm];
20 
21 int n, k, m, maxw, fa[maxn];
22 
23 int dj_find(int i) {
24     if (fa[i] == i) return i;
25     else return fa[i] = dj_find(fa[i]);
26 }
27 
28 inline void dj_merge(int a, int b) {
29     fa[dj_find(a)] = dj_find(b);
30 }
31 
32 inline int check(int x) {
33     int cnt = 0;
34     for (int i = 1; i <= n; ++i) fa[i] = i;
35     for (int i = 1; i <= m - 1; ++i) {
36         if (edge[i].w1 > x) continue;
37         int u = edge[i].u, v = edge[i].v;
38         if (dj_find(u) != dj_find(v)) {
39             dj_merge(u, v);
40             ++cnt;
41         }
42     }
43     if (cnt < k) return 0;
44     for (int i = 1; i <= m - 1; ++i) {
45         if (edge[i].w2 > x) continue;
46         int u = edge[i].u, v = edge[i].v;
47         if (dj_find(u) != dj_find(v)) {
48             dj_merge(u, v);
49             ++cnt;
50         }
51     }
52     if (cnt != n - 1) return 0;
53     else return 1;
54 }
55 
56 int main() {
57     n = get_num(), k = get_num(), m = get_num();
58     for (int i = 1; i <= m - 1; ++i) {
59         edge[i].u = get_num(), edge[i].v = get_num();
60         edge[i].w1 = get_num(), edge[i].w2 = get_num();
61         maxw = max(maxw, edge[i].w1);
62     }
63     int l = 1, r = maxw;
64     while (l < r) {
65         int mid = l + (r - l) / 2;
66         if (check(mid)) r = mid;
67         else l = mid + 1;
68     }
69     printf("%d", l);
70     return 0;
71 }
AC代码(BZOJ、二分)

相关文章:

  • 2022-12-23
  • 2022-02-06
  • 2022-12-23
  • 2022-02-09
  • 2021-05-29
  • 2021-07-30
猜你喜欢
  • 2022-12-23
  • 2021-06-23
  • 2021-05-28
  • 2021-07-04
  • 2021-06-20
  • 2022-12-23
相关资源
相似解决方案