60pts 克鲁斯卡尔算法+删除最大边 求帮调!
查看原帖
60pts 克鲁斯卡尔算法+删除最大边 求帮调!
1091525
banko楼主2024/7/29 16:09
#include<bits/stdc++.h>

using namespace std;
int nodesnum;
int satellite;
struct node {
    int x, y;
};

struct edge {
    int x, y;
    double value;

    bool operator<(const edge &temp) const {
        return value < temp.value;
    }
};

vector<node> nodes;
vector<edge> edges;
int parent[510];
bool satellite_or_not[510];

bool cmp(edge x, edge y) {
    return x.value < y.value;
}

double dist(int x, int y) {
    return sqrt(pow(nodes[x].x - nodes[y].x, 2) + pow(nodes[x].y - nodes[y].y, 2));
}

int fin(int x) {
    if (x != parent[x]) parent[x] = fin(parent[x]);
    return parent[x];
}

priority_queue<edge> pq;
double ans = 0;
int cnt = 0;

void kruskal() {
    sort(edges.begin(), edges.end(), cmp);
    for (int i = 0; i < edges.size(); ++i) {
        int rootx = fin(edges[i].x), rooty = fin(edges[i].y);
        if (rootx != rooty) {
            cnt++;
            parent[rootx] = rooty;
            ans = max(ans, edges[i].value);
            pq.push(edges[i]);
            if (cnt == nodesnum - 1) return;
        }
    }
}

int main() {
    cin >> satellite >> nodesnum;
    nodes.resize(nodesnum + 1);
    for (int i = 1; i <= nodesnum; ++i) {
        cin >> nodes[i].x >> nodes[i].y;
        parent[i] = i;
    }
    for (int i = 1; i <= nodesnum; ++i) {
        for (int j = i + 1; j <= nodesnum; ++j) {
            edges.push_back({i, j, dist(i, j)});
        }
    }
    kruskal();
    if (satellite < 2) printf("%.2f", ans);
    else {
        satellite -= 2;
        //cout<<pq.top().value<<endl;
        satellite_or_not[pq.top().x] = 1, satellite_or_not[pq.top().y] = 1;
        pq.pop();
        ans = pq.top().value;
        while (satellite > 0) {
            int x = pq.top().x, y = pq.top().y;
            if (satellite_or_not[x] || satellite_or_not[y]) {
                satellite_or_not[x] = 1, satellite_or_not[y] = 1;
                pq.pop();
                ans = pq.top().value;
                satellite--;
            } else {
                if (satellite >= 2) {
                    int x = pq.top().x, y = pq.top().y;
                    satellite_or_not[x] = 1, satellite_or_not[y] = 1;
                    pq.pop();
                    ans = pq.top().value;
                    satellite -= 2;
                } else {
                    break;
                }
            }
        }
        printf("%.2f", ans);
    }
}

先求出mst 然后判断卫星电话数量 只有大于等于二才能删边 满足条件删最大边 此后每次最大边两个端点可能有一个是已经有卫星电话了 可能只需要一个卫星电话就行 然后一点一点判断。。。60/100pts 谢谢各位帮忙。。。

2024/7/29 16:09
加载中...