自定义小根堆

在C++中,priority_queue 默认是一个 大根堆(即最大元素在堆顶)。如果想将其改为 小根堆(即最小元素在堆顶),可以通过以下两种方式实现:

方法 1:使用 greater 比较函数

priority_queue 的第三个模板参数可以指定比较函数。使用 greater 可以让 priority_queue 成为小根堆。

修改后的代码:

#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;

struct node1 {
    double x;
    double y;
    int num;
};

struct node {
    node1 x;
    node1 y;
    double dis;
    node(node1 a, node1 b) {
        this->x = a;
        this->y = b;
        dis = sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }
    // 重载 < 运算符,用于比较
    bool operator<(const node& other) const {
        return dis > other.dis;  // 小根堆
    }
};

int parent[101];

void init() {
    for (int i = 0; i < 101; i++) {
        parent[i] = i;
    }
}

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

void Union(int x, int y) {
    int roota = find(x);
    int rootb = find(y);
    if (roota != rootb) {
        parent[roota] = rootb;
    }
}

int main() {
    int n;
    cin >> n;
    vector<node1> res;
    init();
    for (int i = 0; i < n; i++) {
        double x, y;
        cin >> x >> y;
        node1 d;
        d.x = x; d.y = y; d.num = i;
        res.push_back(d);
    }

    // 使用 greater 比较函数,使 priority_queue 成为小根堆
    priority_queue<node, vector<node>, greater<node>> sss;
    for (int i = 0; i < res.size(); i++) {
        for (int j = i + 1; j < res.size(); j++) {
            sss.push(node(res[i], res[j]));
        }
    }

    double sum = 0;
    while (!sss.empty()) {
        node a = sss.top(); sss.pop();
        if (find(a.x.num) != find(a.y.num)) {
            sum += a.dis;
            Union(a.x.num, a.y.num);
        }
    }

    printf("%.2f\n", sum);  // 保留两位小数
}

方法 2:自定义比较函数

如果你不想重载 < 运算符,可以通过自定义比较函数来实现小根堆。

修改后的代码:

#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;

struct node1 {
    double x;
    double y;
    int num;
};

struct node {
    node1 x;
    node1 y;
    double dis;
    node(node1 a, node1 b) {
        this->x = a;
        this->y = b;
        dis = sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }
};

// 自定义比较函数
struct Compare {
    bool operator()(const node& a, const node& b) {
        return a.dis > b.dis;  // 小根堆
    }
};

int parent[101];

void init() {
    for (int i = 0; i < 101; i++) {
        parent[i] = i;
    }
}

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

void Union(int x, int y) {
    int roota = find(x);
    int rootb = find(y);
    if (roota != rootb) {
        parent[roota] = rootb;
    }
}

int main() {
    int n;
    cin >> n;
    vector<node1> res;
    init();
    for (int i = 0; i < n; i++) {
        double x, y;
        cin >> x >> y;
        node1 d;
        d.x = x; d.y = y; d.num = i;
        res.push_back(d);
    }

    // 使用自定义比较函数,使 priority_queue 成为小根堆
    priority_queue<node, vector<node>, Compare> sss;
    for (int i = 0; i < res.size(); i++) {
        for (int j = i + 1; j < res.size(); j++) {
            sss.push(node(res[i], res[j]));
        }
    }

    double sum = 0;
    while (!sss.empty()) {
        node a = sss.top(); sss.pop();
        if (find(a.x.num) != find(a.y.num)) {
            sum += a.dis;
            Union(a.x.num, a.y.num);
        }
    }

    printf("%.2f\n", sum);  // 保留两位小数
}

关键点总结

  1. priority_queue 默认是大根堆,可以通过 greater 或自定义比较函数改为小根堆。
  2. 方法 1:使用 greater<node>,但需要重载 < 运算符。
  3. 方法 2:自定义比较函数,不需要重载 < 运算符。
  4. 两种方法都可以实现小根堆,选择适合你的方式即可。

修正后的代码可以正确计算最小生成树的总权重。

全部评论

相关推荐

不愿透露姓名的神秘牛友
06-29 17:30
找实习找着找着就要进入7月了,马上秋招也要开始了,找实习还有意义吗?
绝迹的星:有面就面, 没面上就当日薪4位数大佬免费培训, 面上了再考虑要不要实习
点赞 评论 收藏
分享
大方的大熊猫准备进厂:1.教育背景:你希望从事什么专业的工作你的主修课就是什么;成绩优秀是你应该做的,没什么可描述的,成绩不优秀也许人家在大学忙着创业呢?(成绩优秀不一定是好事,只能说明多元化的大学你上成了高中,没有真正上明白大学,反而体现了你死板,不爱社交,没有别的突出能力) 2.实践经历:你想表达的意思没有说清楚。你是说你会个性化服务,还是你有实习经历。如果没有带来,经济收益,表彰,更好的发展前景,那你还不如说说提升了自己哪些技能。你说有人给你送锦旗我都能明白你优秀,但是你说你会xxxx,你说这话谁信,证据呢。 3.入伍经历:你描述的就是你的工作职责或者你应该做的,并没有体现出来你把这个事情做好了,而且入伍经历并不能证明你能干好你要应聘的工作,不如只写经历其余所有内容都不写。 4.荣誉技能:重点突出一下,但不要过多描述,这些荣誉的含金量懂得都懂。 重点:你要应聘什么工作(具体岗位,实习生不具体),你的期望薪资
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务