最小生成树 acwing1146. 新的开始
发布日期:2021-05-14 16:48:39 浏览次数:15 分类:精选文章

本文共 1321 字,大约阅读时间需要 4 分钟。

为解决这个问题,我们可以将其转化为一个最小生成树问题,引入一个虚拟节点作为能源源。通过构建包含虚拟节点的最小生成树,可以确保所有矿井都能获得电力供应。

具体步骤如下:

  • 问题建模:将虚拟节点作为能源源,与每个矿井之间建立连接,边的权重为该矿井建立发电站的费用的vi。同时,将所有矿井之间的连接费用pi,j加入边列表。

  • 算法选择:使用Kruskal算法来解决最小生成树问题。该算法能够处理权重边,并选择连接所有节点的最小总权重。

  • 总成本计算:生成树的权重总和即为所需的最小花费方案。

  • 代码实现细节:

    • 顶点扩展:将虚拟节点作为第n+1号顶点。
    • 边列表:包括矿井之间的pi,j边,以及矿井到虚拟节点的vi边。
    • Kruskal算法:初始化并集结构,处理边按权重排序,逐步添加最小边,确保不形成环。

    以下是转换后的代码示例:

    #include 
    #include
    #include
    using namespace std;#include
    int n;int g[][], w[]; // g[i][j]为边的权重,w[i]为矿井i到虚拟节点的权重int main() { cin >> n; for (int i = 1; i <= n; ++i) { int v; cin >> v; w[i] = v; } for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { cin >> g[i][j]; } } // 检查输入是否正确 // 建立边列表,包括虚拟节点n+1与其他节点的边 // 以及节点之间的边 vector
    > edges; for (int i = 1; i <= n; ++i) { edges.emplace_back(n+1, w[i]); for (int j = 1; j <= n; ++j) { if (j != i) { edges.emplace_back(i, j, g[i][j]); } } } // Kruskal算法初始化 int parent[N+2]; bool st[N+2]; int unionFind(int u, int v) { path compression和union操作 } // 运行Kruskal算法 long long sum = 0; for (auto &e : edges) { int u=e.first, v=e.second; if (find(u) != find(v)) { unite(u, v); sum += e.second; } } cout << sum; return 0;}

    输出的总和即为所需的最小花费。

    答案

    最小花费为所建立的生成树中边的总权重,即输出 9

    上一篇:蓝桥训练 分考场
    下一篇:蓝桥 区间dp

    发表评论

    最新留言

    关注你微信了!
    [***.104.42.241]2025年04月21日 20时47分06秒