【Luogu P4047】[JSOI2010]部落劃分
阿新 • • 發佈:2020-07-20
題目大意:
給 \(n\) 個點分組,使得最近的兩組最遠。
正文:
由 最近的兩組最遠
想到二分答案,分組
也可以聯想到並查集。用二分答案,很明顯二分的是“最近的兩組”的距離。而我們可以通過列舉每個點的距離比較當前二分的最近兩組距離,如果小於,說明兩點皆為同一組內。最後可以通過枚舉出的組數比較題目限制的組數調整二分的範圍。
程式碼:
bool check(double x) { for (int i = 1; i <= n; i++) fa[i] = i; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if((a[i].x - a[j].x - 0.0) * (a[i].x - a[j].x - 0.0) + (a[i].y - a[j].y - 0.0) * (a[i].y - a[j].y - 0.0) < x) fa[find_(i)] = find_(j); int cnt = 0; for (int i = 1; i <= n; i++) if(fa[i] == i) cnt++; if(cnt < k) return 0; return 1; } int main() { scanf ("%d%d", &n, &k); for (int i = 1; i <= n; i++) scanf("%d%d", &a[i].x, &a[i].y), maxx = max(a[i].x, maxx), maxy = max(a[i].y, maxy); double l = 0.0, r = maxx * maxx + maxy * maxy, mid; while(1e-4 < r-l) //1e-4是精度問題 { mid = (l + r) / 2.0; if(check(mid)) l = mid; else r = mid; } printf("%.2lf", sqrt(l)); //最後才取根號是精度問題 return 0; }