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;
    }
}
posted @ 2021-03-14 23:08  naymi  阅读(61)  评论(0)    收藏  举报