POJ 2349 Arctic Network
二分 + 最小生成树
容易看到d可以二分,小于d边的直接连接,
最后check的是并查集里面父节点个数
const int maxn = 5e5 + 7;
const double esp = 1e-9;
int t, s, p, cnt, fa[maxn];
double x[maxn], y[maxn];
struct edge {
int st, ed;
double val;
} edg[maxn];
bool cmp(edge e1, edge e2) {
return e1.val < e2.val;
}
int find(int e) {
if (fa[e] == e)
return e;
return fa[e] = find(fa[e]);
}
void cmb(int xx, int yy) {
xx = find(xx), yy = find(yy);
fa[xx] = yy;
}
bool check(double d) {
for (int i = 1; i <= p; i++)
fa[i] = i;
for (int i = 0; i < cnt; i++) {
if (edg[i].val > d)
break;
if (find(edg[i].st) == find(edg[i].ed))
continue;
else
cmb(edg[i].st, edg[i].ed);
}
int res = 0;
for (int i = 1; i <= p; i++)
if (i == find(i))
res++;
return res <= s;
}
void solve() {
cin >> t;
while (t--) {
cnt = 0;
cin >> s >> p;
for (int i = 1; i <= p; i++)
cin >> x[i] >> y[i];
for (int st = 1; st <= p; st++) {
for (int ed = 1; ed <= p; ed++) {
edg[cnt].st = st, edg[cnt].ed = ed;
edg[cnt].val = (x[st] - x[ed]) * (x[st] - x[ed]) + (y[st] - y[ed]) * (y[st] - y[ed]);
cnt++;
}
}
sort(edg, edg + cnt, cmp);
double l = 0, r = 1e18;
while (l + esp < r) {
if (check((l + r) / 2))
r = (l + r) / 2;
else
l = (l + r) / 2;
}
cout << fixed << setprecision(2) << sqrt(l) << endl;
}
}
我看见 你