BZOJ4602: [Sdoi2016] gear (and look up heuristic combination)

Keywords: C++

meaning of the title

Title Link

Give a tree, each node has weight, select \ (k \) connecting blocks, maximize

\[\frac{\sum_{i \in S} a_i}{k}\]

Sol

It's very similar to cc

For the initial \ (N \) points, each additional restriction actually merges two connection blocks.

Then we preprocess \ (val[i] \) to indicate that the root node of the connection block where the \ (I \) node is rotated \ (1 \) and how many turns the node will rotate

And check the set to maintain the connectivity and the size of the connectivity block, and directly heuristic merge is OK

It seems to run very fast

#include<bits/stdc++.h>
#define siz(v) ((int)v.size())
using namespace std;
const int MAXN = 2001;
const double eps = 1e-9;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, M, fa[MAXN], siz[MAXN];
double val[MAXN];
vector<int> v[MAXN];
void init() {
    for(int i = 1; i <= N; i++) fa[i] = i, v[i].clear(), siz[i] = 1, val[i] = 1;
}
int find(int x) {
    return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}
bool dcmp(double x) {
    return fabs(x) < eps;
}
void mem(int x, int fa, double va) {
    for(int i = 0; i < siz(v[x]); i++) {
        int to = v[x][i];
        if(to == fa) continue;
        val[to] *= va;
        mem(to, x, va);
    }
}
bool solve() {
    N = read(); M = read(); bool flag = 0;   
    init();
    for(int i = 1; i <= M; i++) {
        int x = read(), y = read(), fx = find(x), fy = find(y); double vx = read(), vy = read();
        if(flag) continue;
        if(fx == fy) {if(!(dcmp(val[x] / val[y] - vx / vy))) flag = 1; continue;}
        if(siz[fx] > siz[fy]) swap(x, y), swap(vx, vy), swap(fx, fy);
        val[fx] = vx / vy * val[y] / val[x];
        mem(fx, 0, val[fx]); fa[fx] = fy; v[y].push_back(fx);
        siz[fy] += siz[fx]; siz[fx] = 0;
    }
    return flag ^ 1;
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("a.in", "r", stdin);
#endif
    int T = read();
    for(int i = 1; i <= T; i++) {
        printf("Case #%d: ", i);
        puts(solve() ? "Yes" : "No");
    }
    return 0;
}
/*
2
3 3
1 2 3 5
2 3 5 -7
1 3 3 7
3 3
1 2 3 5
2 3 5 -7
1 3 3 -7
*/

Posted by gemmerz on Tue, 10 Dec 2019 09:44:34 -0800