BOJ 9373, ICPC-BAPC 2013 볡λ λ«κΈ°(Getting Through)
νμ΄
λ°μ§λ¦ $r_i$μΈ μμ 컀λ²νλ μΌμ λ€μ΄ μ£Όμ΄μ§λ€. μ΄λ μ΅λνμ λ°μ§λ¦ $x$λ₯Ό κ°μ§ μν λ‘λ΄μ 보λ΄μ, μ΄ μΌμλ€μ νλλ κ±Έλ¦¬μ§ μκ³ ν΅κ³Όν΄μΌ νλ€.
λ²½κ³Ό κ° μΌμλ₯Ό λͺ¨λ μ μ μΌλ‘ μκ°νκ³ , κ° μΌμλ€ (λ²½μ ν¬ν¨) κ°μ 거리λ₯Ό κΈΈμ΄λ‘ κ°λ κ°μ μΌλ‘ μ΄λ€ λͺ¨λλ₯Ό μμ. μ΄μ , μ΄λ€ κ²½λ‘κ° μμͺ½ λ²½ μ μ μ μλλ€κ³ μκ°νμ.
μμͺ½ λ²½μ μλ κ²½λ‘λ μ°λ¦¬κ° λ‘λ΄μΌλ‘ μ§νν κ²½λ‘μ λ°λμ κ²ΉμΉλ€. λ°λΌμ, λ²½μ μλ κ²½λ‘ Pλ μ°λ¦¬κ° λ§λ€ μ μλ λ‘λ΄ μ§κ²½μ boundλ₯Ό μ 곡νλ€. μ΄λ₯Ό μμΌλ‘ μκ°νλ©΄, λ²½μ μλ μμμ κ²½λ‘ Pλ₯Ό ν΅κ³Όν μ μλ μ§κ²½μ λ‘λ΄μ λ§λ€μ΄μΌ νλ€λ κ²μ΄λ€.
λ°λΌμ, λ λ²½μ μλ μμμ κ²½λ‘ μ€, κ°μ μ μ΅λκ°μ΄ κ°μ₯ μμ κ²½λ‘λ₯Ό μ°ΎμμΌ νλ€. μ΅λκ° μΈ μ΄μ λ λ‘λ΄μ νμ μ΅μ μ λ€ν΄ μμΌλ‘ λκ°λ €κ³ νλ―λ‘, μμμ κ²½λ‘ μ€ μ΅λκ°μ΄ κ°μ₯ μμ κ²½λ‘λ₯Ό μ§λ μ μλ€λ©΄ λͺ¨λ κ²½λ‘λ₯Ό μ§λ μ μκΈ° λλ¬Έμ΄λ€. μ΄λ₯Ό μ μκ°ν΄ 보면, MSTλ₯Ό λ§λλ κ²μ²λΌ κ°μ λ€μ μΆκ°νλ€κ°, μμͺ½ λ²½μ΄ ν©μ³μ§λ μκ° λ©μΆλ©΄ μ£Όμ΄μ§ 쑰건μ κ²½λ‘λ₯Ό μ°Ύμ μ μμμ μλ€.
μ½λ
μμ κΈΈμ΄μ κ°μ μ λ§λ€μ§ μλλ‘ μ£Όμνμ. μμ΄ κ²ΉμΉ λ μ μ μ μμ ν©μ³μ€λ λκΈ°λ νλλ°..κ΅³μ΄?
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#define ll long long
#define eps 1e-7
#define all(x) ((x).begin()),((x).end())
#define usecppio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
#define int ll
using pii = pair<int, int>;
struct pt
{
double x, y, r;
};
double dt(pt &a, pt &b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
struct edge
{
int u, v;
double w;
bool operator<(const edge &o)
{
return w < o.w;
}
};
vector <edge> elist;
int SC = 1005, SK = 1006;
struct DSU
{
#define V 1010
int par[V], sz[V];
DSU(){init(V);}
void init(int n)
{
for (int i = 0; i<n; i++)
par[i] = i, sz[i] = 1;
}
int find(int x)
{
return x == par[x] ? x : (par[x] = find(par[x]));
}
int getSize(int k){return sz[find(k)];}
void unite(int x, int y)
{
int u=find(x), v=find(y);
if(u==v) return;
if(sz[u]>sz[v]) swap(u, v);
sz[v]+=sz[u];
sz[u] = 0;
par[u] = par[v];
}
} D;
pt pts[1010];
void solve()
{
D.init(V);
double W; cin >> W;
int n; cin >> n;
if (n == 0)
{
cout << fixed << setprecision(20) << W / 2 << '\n';
return;
}
for (int i = 0; i < n; i++)
{
cin >> pts[i].x >> pts[i].y >> pts[i].r;
elist.push_back({SC, i, max(0.0, pts[i].x - pts[i].r)});
elist.push_back({SK, i, max(0.0, W - pts[i].x - pts[i].r)});
}
for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++)
elist.push_back({i, j, max(0.0, dt(pts[i], pts[j]) - pts[i].r - pts[j].r)});
sort(all(elist));
double ans = 0;
for (auto e : elist)
{
D.unite(e.u, e.v);
if (D.find(SK) == D.find(SC))
{
ans = e.w / 2;
break;
}
}
cout << fixed << setprecision(20) << ans << '\n';
}
int32_t main()
{
usecppio
int T; cin >> T;
while(T--)
{
elist.clear();
solve();
}
}