C - Safe Distance(二分&DSU)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C - Safe Distance(二分&DSU)相关的知识,希望对你有一定的参考价值。
C - Safe Distance(二分&DSU)
显然答案具有二分性,然后就是套路性对每个点化圆。
考虑无解的情况,假设分成上下左右四个区域,显然上下连通或者左右连通无解,通路左下或右上连通无解。因此考虑对于相交的两圆进行并查集合并。
然后就裸了。
参考别人代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
struct Res {
double x, y;
void read() {
scanf("%lf %lf", &x, &y);
}
}a[N];
int fa[N], n, X, Y; // {n + 1, 上表面} {n + 2, 下表面} {n + 3, 左表面} {n + 4, 右表面}
int find(int rt) {
return rt == fa[rt] ? rt : fa[rt] = find(fa[rt]);
}
double Dis(Res a, Res b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool judge(double x) {
for (int i = 1; i <= n + 4; i++) {
fa[i] = i;
}
for (int i = 1; i <= n; i++) {
if (a[i].y + x > Y) {
int u = find(i), v = find(n + 1);
fa[u] = v;
}
if (a[i].y < x) {
int u = find(i), v = find(n + 2);
fa[u] = v;
}
if (a[i].x < x) {
int u = find(i), v = find(n + 3);
fa[u] = v;
}
if (a[i].x + x > X) {
int u = find(i), v = find(n + 4);
fa[u] = v;
}
for (int j = 1; j < i; j++) {
if (Dis(a[i], a[j]) < 2 * x) {
int u = find(i), v = find(j);
fa[u] = v;
}
}
}
if ((find(n + 1) == find(n + 2)) || (find(n + 1) == find(n + 4)) || (find(n + 3) == find(n + 2)) || (find(n + 3) == find(n + 4))) {
return false;
}
return true;
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
scanf("%d %d %d", &X, &Y, &n);
for (int i = 1; i <= n; i++) {
a[i].read();
}
double l = 0, r = max(X, Y);
for (int i = 1; i <= 100; i++) {
double mid = 0.5 * (l + r);
if (judge(mid)) {
l = mid;
}
else {
r = mid;
}
}
printf("%.10f\\n", l);
return 0;
}
以上是关于C - Safe Distance(二分&DSU)的主要内容,如果未能解决你的问题,请参考以下文章
[LeetCode&Python] Problem 821. Shortest Distance to a Character
hihoCoder 1238 : Total Highway Distance(dfs + 二分)
HDU - 6621 K-th Closest Distance 主席树+二分答案
HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)