[SDOI2012] to save the princess Xiaoyun

Topic links:

topic

analysis

Maximum minimum minimum maximum one look very half
after considering half converted to determine Unicom problem
can then consider cheese
directly maintain Unicom seems to be \ (GG \) , being difficult the anti consider maintenance is not connected
when not connected, found that when the top left and bottom right points in two blocks inside to cool it
when the upper and lower and right or left and right corners when Unicom is divided in two
other two cases in the same way
so the disjoint-set modeled after cheese maintain it, If four kinds of instructions can go no Unicom
then sets dichotomous complexity \ (O (n ^ 2 * log (n)) \) this code may be oxygen through

#include<bits/stdc++.h>
#define eps 1e-8
#define N (3000 + 10)
using namespace std;
inline int read() {
    int cnt = 0, f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
    while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + (c ^ 48); c = getchar();}
    return cnt * f;
}
int n, R, L, fa[N];
double ans;
struct node {
    double x, y;
}a[N];
int get_fa(int x) {return x == fa[x] ? x : fa[x] = get_fa(fa[fa[fa[fa[x]]]]);}
double Pow(double x) {return x * x;}
bool dis(node a, node b, double r) {
    return (r * r * 4 - Pow(a.x - b.x) - Pow(a.y - b.y)) > 0;
}
bool check(double r) {
    for (register int i = 1; i <= n + 2; ++i) fa[i] = i;
    for (register int i = 1; i <= n; ++i) {
        if (a[i].x - r <= 1 || a[i].y + r >= L) fa[i] = n + 1;
        if (a[i].x + r >= R || a[i].y - r <= 1) fa[get_fa(i)] = n + 2;
    }
    for (register int i = 1; i <= n; ++i)
        for (register int j = i; j <= n; ++j) {
            int fx = get_fa(i), fy = get_fa(j);
            if (fx == fy) continue;
            if (!dis(a[i], a[j], r)) continue;
            fa[fx] = fy;
            if (get_fa(n + 1) == get_fa(n + 2)) return false;
        }
    if (get_fa(n + 1) == get_fa(n + 2)) return false;
    return true;
}
inline double binary() {
    double l = 0, r = min(L, R);
    double mid = (l + r) / 2.0;
    while (r - l > eps) {
//      cout<<l<<" "<<r<<endl;
        if (check(mid)) l = mid;
        else r = mid;
        mid = (l + r) / 2.0;
    }
    return mid;
}
int main() {
//  freopen("1.in", "r", stdin);
//  freopen("own.out", "w", stdout);
    n = read(), R = read(), L = read();
    for (register int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read();
    ans = binary();
    printf("%.2lf", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/kma093/p/11622303.html