P2498 [SDOI2012]拯救小云公主

Posted olinr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2498 [SDOI2012]拯救小云公主相关的知识,希望对你有一定的参考价值。

(color{#0066ff}{ 题目描述 })

英雄又即将踏上拯救公主的道路……

这次的拯救目标是——爱和正义的小云公主。

英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是上千只boss。当英雄意识到自己还是等级1的时候,他明白这就是一个不可能完成的任务。

但他不死心,他在想,能不能避开boss去拯救公主呢,嘻嘻。

Boss的洞穴可以看成一个矩形,英雄在左下角(1,1),公主在右上角(row,line)。英雄为了避开boss,当然是离boss距离越远越好了,所以英雄决定找一条路径使到距离boss的最短距离最远。

Ps:英雄走的方向是任意的。

你可以帮帮他吗?

当英雄找到了美丽漂亮的小云公主,立刻就被boss包围了!!!英雄缓闭双眼,举手轻挥,白光一闪后使用了回城卷轴,回到了城堡,但只有小云公主回去了……因为英雄忘了进入回城的法阵了。

(color{#0066ff}{输入格式})

第一行,输入三个整数,n表示boss的数目,row,line表示矩形的大小;

接下来n行,每行分别两个整数表示boss的位置坐标。

(color{#0066ff}{输出格式})

输出一个小数,表示英雄的路径离boss的最远距离,精确到小数点后两位。

(color{#0066ff}{输入样例})

1 3 3
2 2
    
1 3 3
3 1

(color{#0066ff}{输出样例})

1.00
    
2.00

(color{#0066ff}{数据范围与提示})

20%数据,boss坐标范围小于等于50;

60%数据,n<=1500;

100%数据,n<=3000;

(color{#0066ff}{ 题解 })

显然要二分答案

于是,问题就变成了二维奶酪(见NOIP2017 奶酪

(O(n^2logn)),卡卡二分就过了

#include<bits/stdc++.h>
#define LL long long
LL in() {
    char ch; LL x = 0, f = 1;
    while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    return x * f;
}
const int maxn = 3505;
int n;
bool flag;
double X, Y;
struct node {
    double x, y;
    node(double x = 0, double y = 0): x(x), y(y) {}
}e[maxn];
std::vector<int> v[maxn];
bool vis[maxn];
double D[maxn][maxn];
std::queue<int> q;
bool ok(double mid) {
    while(!q.empty()) q.pop();
    for(int i = 1; i <= n; i++) {
        if(e[i].x < mid || Y - e[i].y < mid) q.push(i), vis[i] = true;
        else vis[i] = false;
    }
    while(!q.empty()) {
        int tp = q.front(); q.pop();
        if(X - e[tp].x < mid || e[tp].y < mid) return false;
        for(int i = 1; i <= n; i++) if(!vis[i] && D[tp][i] < mid * mid * 4.0) vis[i] = true, q.push(i);
    }
    return true;
}
int main() {
    n = in(), X = in() - 1, Y = in() - 1;
    for(int i = 1; i <= n; i++) e[i].x = in() - 1, e[i].y = in() - 1; 
    for(int i = 1; i <= n; i++)
        for(int j = i + 1; j <= n; j++) {
            node a = e[i], b = e[j];
            D[i][j] = D[j][i] = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        }
    double l = 0, r = std::min(X, Y), ans = r;
    int t = 200;
    while(t--) {
        double mid = (l + r) / 2.0;
        if(ok(mid)) ans = mid, l = mid;
        else r = mid;
    }
    printf("%.2f", ans);
    return 0;
}

以上是关于P2498 [SDOI2012]拯救小云公主的主要内容,如果未能解决你的问题,请参考以下文章

二分+并查集bzoj3007[SDOI2012]拯救小云公主

[SDOI2012]拯救小云公主

bzoj3007拯救小云公主 二分+对偶图+并查集

BZOJ:4219: 跑得比谁都快 3007: 拯救小云公主

[BZOJ 3007] 拯救小云公主 对偶图

BZOJ 3007 解救小云公主 二分答案+对偶图