社区讨论

40pts 注释我自认为写的很详细

P1991无线通讯网参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@m4jnc9mg
此快照首次捕获于
2024/12/11 16:46
去年
此快照最后确认于
2025/11/04 13:01
4 个月前
查看原帖
卫星电话 -> 微信电话。
因为只要有网,微信电话就能打(doge)。
CPP
#include <iostream> // macOS 用不了那个东西
#include <vector>
#include <algorithm>
#include <cmath>
#define MAXN 505
using namespace std;
struct Point {
    int x, y;
    Point() {
        x = y = 0;
    }
} a[MAXN]; // 每个点
struct Edge{
    int u, v;
    double l;
} e[MAXN*MAXN]; // 每条边
int k, n, m, fa[MAXN]; // k 表示可以安装微信电话的数量,n 表示哨所的数量,m 表示边的数量
bool vis[MAXN]; // 这个节点是否安装了微信电话


double distBetween(Point a, Point b) {
    return sqrt(pow(a.x-b.x, 2.0)+pow(a.y-b.y, 2.0));
}
int find(int x) {
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y) {
    fa[find(x)] = find(y);
}
bool operator< (Edge a, Edge b) { // 排序边用到
    return a.l < b.l;
}
bool operator> (Edge a, Edge b) { // 排序边用到
    return a.l > b.l;
}
int main() {
    cin >> k >> n;
    for (int i = 1; i <= n; i++) { // 输入并初始化并查集
        cin >> a[i].x >> a[i].y;
        fa[i] = i;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (i == j) continue;
            e[++m].u = i;
            e[m].v = j;
            e[m].l = distBetween(a[i], a[j]);
        }
    }
    sort(e+1, e+m+1);
    vector<Edge> selectedEdge; // 选择的边(名字写的很明白了吧。。。)
    for (int i = 1; i <= m; i++) { // Kruskal 启动!
        if (find(e[i].u) != find(e[i].v)) {
            selectedEdge.push_back(e[i]);
            merge(e[i].u, e[i].v);
        }
    }
    sort(selectedEdge.begin(), selectedEdge.end(), greater<Edge>()); // 从大到小排序
    int ansindex = 0;
    for (int i = 0; i < selectedEdge.size(); i++) {
        int u = selectedEdge[i].u, v = selectedEdge[i].v;
        if (k <= 0) break; // 如果微信电话用完了
        if (!vis[u]) { // 如果 u 没装微信电话
            vis[u] = 1;
            k--;
        }
        if (!vis[v]) { // 如果 v 没装微信电话
            vis[v] = 1;
            k--;
        }
        ansindex = i;
    }
    printf("%.2f\n", selectedEdge[++ansindex].l);
    // 因为 ansindex 是最后一对安装微信电话的边,那么第一对没有安装的就是答案
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...