#include #include #include #include #include #include #include #include using namespace std; using F = int; struct S { const int v; // neighbour const int r; // index of the reverse edge F f; // current flow const F cap; // capacity S(int v, int ri, F c) : v(v), r(ri), f(0), cap(c) {} }; struct FlowGraph : vector> { FlowGraph(size_t n) : vector>(n) {} void add_edge(int u, int v, F c = 1) { auto &t = *this; t[u].emplace_back(v, t[v].size(), c); t[v].emplace_back(u, t[u].size() - 1, 0); } }; struct Dinic { FlowGraph &edges; int V, s, t; vector l; vector::iterator> its; // levels and iterators Dinic(FlowGraph &edges, int s, int t) : edges(edges), V(edges.size()), s(s), t(t), l(V, -1), its(V) {} int augment(int u, F c) { // we reuse the same iterators if(u == t) return c; for(auto &i = its[u]; i != edges[u].end(); i++) { auto &e = *i; if(e.cap > e.f && l[u] < l[e.v]) { auto d = augment(e.v, min(c, e.cap - e.f)); if(d > 0) { e.f += d; edges[e.v][e.r].f -= d; return d; } } } return 0; } int run() { int flow = 0, f; while(true) { fill(l.begin(), l.end(), -1); l[s] = 0; // recalculate the layers queue q; q.push(s); while(!q.empty()) { auto u = q.front(); q.pop(); for(auto &&e : edges[u]) if(e.cap > e.f && l[e.v] < 0) l[e.v] = l[u] + 1, q.push(e.v); } if(l[t] < 0) return flow; for(int u = 0; u < V; ++u) its[u] = edges[u].begin(); while((f = augment(s, 1e9)) > 0) flow += f; } } }; struct P { int x, y; }; int dist(P &l, P &r) { return (l.x - r.x) * (l.x - r.x) + (l.y - r.y) * (l.y - r.y); } struct D { int b, r, dist; bool operator<(const D &x) { return tie(dist, b, r) < tie(x.dist, x.b, x.r); } }; int main() { int n, b, r; cin >> n >> b >> r; vector

bs(b), rs(r); for(auto &p : bs) cin >> p.x >> p.y; for(auto &p : rs) cin >> p.x >> p.y; vector dists; dists.reserve(b * r); for(int i = 0; i < b; ++i) for(int j = 0; j < r; ++j) dists.push_back({i, j, dist(bs[i], rs[j])}); sort(dists.begin(), dists.end()); FlowGraph g(b + r + 2); int s = b + r, t = b + r + 1; for(int i = 0; i < b; ++i) g.add_edge(s, i); for(int j = 0; j < r; ++j) g.add_edge(b + j, t); Dinic dinic(g, s, t); int flow = 0; int maxdist = -1; for(auto &d : dists) { g.add_edge(d.b, b + d.r); flow += dinic.run(); // cerr << "n=" << r + b - flow + 1 << " -> " << d.dist << '\n'; if(flow > r + b - n) { maxdist = d.dist; goto end; } } assert(false); end:; cout << fixed << setprecision(15) << sqrt((long double)maxdist) << endl; return 0; }