二分边界
查看原帖
二分边界
124683
Krystallos楼主2020/11/10 15:30

这个是我的屑做法

#include <algorithm>
#include <cstdio>
#include <iostream>
const int nn = 5e4 + 5;
const int mm = 1e5 + 5;
int n, m, k;
struct line {
    int p, q, w, color;
    inline int operator<(const line &p) const {
        return w == p.w ? color < p.color : w < p.w;
    }
} edge[mm];
int father[nn];
int getfather(int p) {
    return p == father[p] ? p : father[p] = getfather(father[p]);
}
int merge(int p, int q) {
    p = getfather(p);
    q = getfather(q);
    if (p == q) return 0;
    father[p] = q;
    return 1;
}
int ask(int val, int &res) {
    for (int i = 1; i <= m; i++) {
        if (!edge[i].color) {
            edge[i].w += val;
        }
    }
    for (int i = 0; i <= n; i++) father[i] = i;
    std::sort(edge + 1, edge + m + 1);
    int cnt = 0, tot = 0;
    for (int i = 1; cnt < n - 1; i++) {
        if (merge(edge[i].p, edge[i].q)) {
            ++cnt;
            tot += !edge[i].color;
            res += edge[i].w;
        }
    }
    for (int i = 1; i <= m; i++) {
        if (!edge[i].color) {
            edge[i].w -= val;
        }
    }
    return tot;
}
int main() {
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 1; i <= m; i++)
        scanf("%d %d %d %d", &edge[i].p, &edge[i].q, &edge[i].w,
              &edge[i].color);
    int l = -100, r = 100, mid, ans, sum;
    while (l < r) {
        mid = l + r >> 1;
        sum = 0;
        int tot = ask(mid, sum);
        if (tot >= k) {
            l = mid + 1;
            ans = sum - k * mid;
        } else
            r = mid - 1;
    }
    printf("%d", ans);
}

它能拿到 85 分
然后为啥把第 53 行的 while (l < r) 改成 while (l <= r) 就能过?

2020/11/10 15:30
加载中...