村村通工程(Kruskal算法)

这篇具有很好参考价值的文章主要介绍了村村通工程(Kruskal算法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

题目描述

思路分析

AC代码


题目描述

"村村通"是国家一个系统工程,其包涵有:公路、电力、生活和饮用水、电话网、有线电视网、互联网等等。

村村通公路工程,是国家为构建和谐社会,支持新农村建设的一项重大举措,是一项民心工程。又称“五年千亿元”工程

该工程是指中国力争在5年时间实现所有村庄通沥青路或水泥路,以打破农村经济发展的交通瓶颈,解决9亿农民的出行难题。

现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

要求用Kruskal算法求解

输入

第1行:顶点数n

第2行:n个顶点编号

第3行:边数m

接着m行:m条边信息,格式为:顶点1 顶点2 权值

输出

第1行:输出最小生成树的权值之和

接着n-1行对应n-1条边信息

如果能找到最小生成树,按树的生长顺序输出, 边顶点按数组序号升序输出

如果输入数据不足以保证畅通,则直接输出−1,无需输出任何边信息

输入样例1

6
v1 v2 v3 v4 v5 v6 
10
v1 v2 6
v1 v3 1
v1 v4 5
v2 v3 5
v2 v5 3
v3 v4 5
v3 v5 6
v3 v6 4
v4 v6 2
v5 v6 6

输出样例1

15
v1 v3 1
v4 v6 2
v2 v5 3
v3 v6 4
v2 v3 5

思路分析

克鲁斯卡尔算法的思想是逐步选择边来构建最小生成树。具体步骤如下:

  1. 将图中的所有边按照权值从小到大进行排序。
  2. 从权值最小的边开始,依次考虑每条边:
    • 如果该边的两个顶点不在同一个连通分量中,则选择该边加入最小生成树,并合并这两个顶点所在的连通分量。
    • 如果该边的两个顶点已经在同一个连通分量中,则舍弃该边,以避免形成环路。
  3. 重复步骤2,直到最小生成树中包含图中的所有顶点为止。

通过这种方式,克鲁斯卡尔算法能够找到一个连通图的最小生成树,并且保证总权值最小。算法的关键在于选择边的过程中保证不会形成环路,以确保最终生成的树是连通的。文章来源地址https://www.toymoban.com/news/detail-499021.html

AC代码

#include<iostream>
#include<vector>

using namespace std;
const int MaxLength = 100;
struct Vertex {
    int index;
    string data;
} vertex[MaxLength];
struct Path {
    int head;
    int tail;
};

class Map {
    int matrix[MaxLength][MaxLength] = {0};
    int vertexNumber;
    int sumCost = 0;
    vector<Path> path;
    int close[MaxLength];
    int count=0;
public:
    Map() {
        cin >> vertexNumber;
        for(int i=0;i<vertexNumber;i++)
            close[i]=i;
        for (int i = 0; i < vertexNumber; i++) {
            cin >> vertex[i].data;
            vertex[i].index = i;
        }
        int edgeNumber;
        cin >> edgeNumber;
        for (int i = 0; i < edgeNumber; i++) {
            string tail, head;
            int cost;
            cin >> tail >> head >> cost;
            matrix[GetIndex(tail)][GetIndex(head)] = matrix[GetIndex(head)][GetIndex(tail)] = cost;
        }
        Kruskal();
    }

    int GetIndex(string &data) {
        for (int i = 0; i < vertexNumber; i++)
            if (vertex[i].data == data)
                return i;
    }
    void Merge(int&x,int&y){
        close[GetRoot(y)]= GetRoot(x);
    }
    int GetRoot(int&x){
        if(close[x]==x)
            return x;
        return GetRoot(close[x]);
    }
    void Kruskal() {
        for(int k=0;k<vertexNumber-1;k++){
            int minCost=0x3f3f3f3f,tail=0,head=0;
            for(int i=0;i<vertexNumber;i++)
                for(int j=i+1;j<vertexNumber;j++)
                    if(matrix[i][j]&&minCost>matrix[i][j]&& GetRoot(i)!= GetRoot(j)){
                        head=i;
                        tail=j;
                        minCost=matrix[i][j];
                    }
            Merge(head,tail);
            Path pass = {head, tail};
            path.push_back(pass);
            sumCost += minCost;
            if(tail||head)
                count++;
        }
        if(count==vertexNumber-1){
            cout << sumCost << endl;
            for (auto &it: path)
                cout << vertex[it.head].data << ' ' << vertex[it.tail].data << ' ' << matrix[it.head][it.tail] << endl;
        }
        else cout<<"-1"<<endl;
    }
};

int main() {
    Map test;
}

到了这里,关于村村通工程(Kruskal算法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 最小生成树(Prim算法,Kruskal算法)

    (1)生成树: 如果在一个无向连通图不包含回路(连通图中不存在环),则为一个树 (2)最小生成树(minimal spanning tree): 在一个图所有生成树中,代价最小的生成树称为最小生成树 (3)生成树的代价: 在一个无向连通网中,生成树各边的权值之和称为该生成树的代价

    2024年02月08日
    浏览(27)
  • 最小生成树——Kruskal算法

    目录 基本思想 实现 伪代码 实际问题求解 最小生成树 :带权连通图的生成树中 边的权值之和最小的生成树。 最小生成树不是唯一的。当图中的各边权值互不相等时,最小生成树是唯一的; 若无向连通图本身是一棵树时(边数比顶点数少1 ),则最小生成树就是它本身。 最

    2023年04月26日
    浏览(38)
  • Kruskal 算法 最小生成树

    1.按边从小到大进行排序 2.从小到大进行加边,保证加入的边的两端点不连通,即保证不形成回路

    2024年02月10日
    浏览(31)
  • Kruskal 算法介绍

    构造最小生成树还有一种算法,即 Kruskal 算法:设图 G=(V,E)是无向连通带权图,V={1,2,...n};设最小生成树 T=(V,TE),该树的初始状态只有 n 个节点而无边的非连通图T=(V,{}),Kruskal 算法将这n 个节点看成 n 个孤立的连通分支。它首先将所有边都按权值从小到大排序,然

    2024年02月05日
    浏览(33)
  • Kruskal算法

    前置知识 :并查集、图的存储、贪心思想 为了保证学习效果,请保证已经掌握前置知识之后,再来学习本章节!如果在阅读中遇到困难,也可以回到前面章节查阅。 适用于稀疏图,时间复杂度 O(mlogm)O(mlogm)。 核心思想:从小到大挑不多余的边,属于贪心的算法。 之前介绍

    2024年02月08日
    浏览(22)
  • 【图论】kruskal算法

     Kruskal(克鲁斯卡尔)算法是一种用于解决最小生成树问题的贪心算法。 最小生成树是指在一个连通无向图中,选择一棵包含所有顶点且边权重之和最小的树。 下面是Kruskal算法的基本步骤: 将图中的所有边按照权重从小到大进行 排序 。 创建一个空的最小生成树 集合(并

    2024年02月15日
    浏览(25)
  • 最小生成树—Kruskal算法和Prim算法

    连通图:在无向图中,若从顶点v1到顶点v2有路径,则称顶点v1与顶点v2是连通的。如果图中任 意一对顶点都是连通的,则称此图为连通图。 生成树:一个连通图的最小连通子图称作该图的生成树。有n个顶点的连通图的生成树有n个顶点 和n-1条边。 最小生成树:构成生成树的

    2024年02月05日
    浏览(32)
  • 最小生成树算法之Kruskal算法(c++)

    与Prim算法生成图的最小生成的树算法不同在于: Prim算法是基于图中的顶点的,且不依赖于边,Prim从顶点出发拓展,依次找每个顶点相邻的权值最小的边,直至生成最小生成树。因此,Prim算法的时间复杂度是O(v^2),适合边稠密图。 而Kruskal算法恰恰相反,是基于图中的边的一

    2024年02月12日
    浏览(31)
  • 最小生成树(Prim算法与Kruskal算法)

    一个连通图的生成树是一个极小的连通子图,它含有图中全部的n个顶点,但只有足以构成一棵树的n-1条边。我们把构造连通网的最小代价生成树称为最小生成树。 例如下图中①、②、③都是左侧图的生成树,但③是构造连通网的最小代价,所以③是该图的最小生成树。 P

    2024年02月05日
    浏览(46)
  • Prim算法和Kruskal算法到底哪个好?

    今天做了一道最小生成树的题,发现了一点猫腻! 题目在这里 : 《修路问题1》 Prim算法 和 Kruskal算法 都是从连通图中找出 最小生成树 的经典算法~ 从策略上来说, Prim算法是直接查找,多次寻找邻边的权重最小值 ,而 Kruskal是需要先对权重排序后查找的 ~ 所以说, Kru

    2024年02月05日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包