bzoj2654: tree (binary minimum spanning +)

topic

bzoj2654: tree

Resolve

kruscal press weights sorted doing the minimum spanning tree, small weights to be elected to, we can control the number of white side by controlling the right side of the white side.
We can give a certain value through the white side plus half the answer
at the same time pay attention to two points

  1. Do not forget to subtract the value added to the white side
  2. White edge prior sorting

Code

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int n, m, num, need, ans, tot, sum, cnt;

int fa[N], head[N], w[N];

struct node {
    int u, v, w, col;
    bool operator <(const node &oth) const {
        return w == oth.w ? col < oth.col : w < oth.w;
    }
} e[N], tmp[N];

int find(int x) {
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}

int kruscal() {
    cnt = 0, sum = 0, ans = 0;
    for (int i = 1; i <= n; ++i) fa[i] = i;
    sort(e + 1, e + 1 + m);
    for (int i = 1; i <= m; ++i) {
        int x = find(e[i].u), y = find(e[i].v);
        if (x == y) continue;
        fa[x] = y;
        ans += e[i].w;
        if (!e[i].col) sum++;
        cnt++;
        if (cnt == n - 1) break;
    }
    return sum;
}

bool check(int x) {
    for (int i = 1; i <= m; ++i) {
        e[i] = tmp[i];
        if (!e[i].col) e[i].w += x;
    }
    return kruscal() >= need;
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> need;
    for (int i = 1, x, y, z, c; i <= m; ++i) {
        cin >> x >> y >> z >> c;
        e[i] = (node) {x + 1, y + 1, z, c};
        tmp[i] = (node) {x + 1, y + 1, z, c};
    }
    int l = -1000, r = 1000;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (check(mid)) l = mid + 1, tot = ans - need * mid;
        else r = mid - 1;
    }
    cout << tot;
    return 0;
}

Guess you like

Origin www.cnblogs.com/lykkk/p/11223011.html