30pts求助
查看原帖
30pts求助
168597
DraTelligence楼主2022/9/27 22:10

试了并查集和bfs都只对了#1#3#9,求问这题其他数据有啥特点吗,,,

码:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;

ll read() {
    register ll n = 0, s = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') s = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        n = (n << 1) + (n << 3) + c - '0';
        c = getchar();
    }
    return s * n;
}

// P2498 [SDOI2012]拯救小云公主
ll dis[3005][3005];
bool up[3005], down[3005];
ll row, line;
int cnt, head[3005];
bool vis[3005];

template <class T>
T mmin(const T& a, const T& b) {
    if (a < b) {
        return a;
    }
    return b;
}

struct pos {
    int x, y;
} boss[3005];

struct edge {
    int to, next, from;
    ll len;
} e[3000004];

void addEdge(const int& a, const int& b) {
    cnt += 1;
    e[cnt].to = b;
    e[cnt].from = a;
    e[cnt].next = head[a];
    head[a] = cnt;
    return;
}

bool check(const double& r, const int& n) {
    // build map
    cnt = 0;
    memset(head, -1, sizeof(head));
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= i; j++) {
            if (dis[i][j] < r) {
                addEdge(i, j);
                addEdge(j, i);
            }
        }
        if (dis[i][3004] < r) {
            addEdge(i, 3004);
            addEdge(3004, i);
        }
    }

    int now = 0;
    queue<int> q;
    q.push(0);
    while (!q.empty()) {
        now = q.front();
        q.pop();

        for (int i = head[now]; i != -1; i = e[i].next) {
            if (vis[e[i].to]) {
                continue;
            }
            if (dis[e[i].from][e[i].to] < r) {
                vis[e[i].to] = true;
                q.push(e[i].to);
            }
        }
    }

    if (vis[3004]) {
        return false;
    }

    return true;
}

int main() {
    double l = 0, r, mid;
    double min = numeric_limits<double>::max();
    ll n = read();
    row = read(), line = read();

    for (int i = 1; i <= n; i++) {
        boss[i].x = read();
        boss[i].y = read();

        min = mmin(min, sqrt(pow(boss[i].x - 1, 2) + pow(boss[i].y - 1, 2)));

        for (int j = 0; j <= i; j++) {
            if (j == 0) {
                dis[j][i] = dis[i][j] =
                    sqrt(mmin(pow(boss[i].x - 1, 2), pow(boss[i].y - line, 2)));
                continue;
            }

            dis[j][i] = dis[i][j] = sqrt(pow(boss[i].x - boss[j].x, 2) +
                                         pow(boss[i].y - boss[j].y, 2));
        }
        dis[i][3004] =
            sqrt(mmin(pow(boss[i].x - row, 2), pow(boss[i].y - 1, 2)));
        dis[3004][i] = dis[i][3004];
    }

    r = min;
    while (r - l >= 0.0001) {
        mid = (l + r) / 2;
        if (check(mid, n)) {
            l = mid;
        } else {
            r = mid;
        }
    }

    printf("%.2f", mid);

    return 0;
}
2022/9/27 22:10
加载中...