供水管线 码蹄集

news2025/1/8 3:46:01

题目来源:码蹄集

题目描述:

在这里插入图片描述
在这里插入图片描述

解决思路:

首先,题目要求我们去掉一些管道,使得总的管道管理费用最小。在去掉部分管道的情况下,城市之间不再形成一个回路,即城市之间构成了一棵树。因此,我们需要找到一棵生成树,使得所有管道管理费用之和最小。

接下来,我们需要选择合适的算法来寻找最小生成树。常用的算法有 Kruskal 算法和 Prim 算法,本题使用 Kruskal 算法实现。

Kruskal 算法的实现步骤如下:

  1. 将所有边按照管道管理费用从小到大排序;

  2. 依次枚举每条边,如果加入该边不会导致出现环,则将其加入生成树中;

  3. 当生成树的边数等于 n-1 时,停止枚举。

其中,n 表示城市的数量,生成树的边数为 n-1。

为了判断加入一条边是否会形成环,我们使用并查集维护已经加入生成树中的点的连通关系。具体地,我们让每个节点所在的集合的代表元素相同,这样就能够快速判断两个节点是否属于同一个集合。

最后,根据 Kruskal 算法得到的最小生成树,计算所有边的管理费用之和即可。

Python代码实现:

from typing import List, Tuple
import sys

class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0] * n

    def find(self, i):
        if self.parent[i] != i:
            self.parent[i] = self.find(self.parent[i])
        return self.parent[i]

    def union(self, i, j):
        pi, pj = self.find(i), self.find(j)
        if pi == pj:
            return False
        if self.rank[pi] < self.rank[pj]:
            pi, pj = pj, pi
        self.parent[pj], self.rank[pi] = pi, max(self.rank[pi], self.rank[pj]+1)
        return True

def min_cost(n: int, edges: List[Tuple[int, int, int]]) -> int:
    uf = UnionFind(n)
    edges.sort(key=lambda e: e[2])
    mst_cost, num_edges = 0, 0
    for u, v, w in edges:
        if uf.union(u-1, v-1):
            mst_cost += w
            num_edges += 1
            if num_edges == n - 1:
                break
    return mst_cost

n, k = map(int, sys.stdin.readline().rstrip().split())
edges = [tuple(map(int, sys.stdin.readline().rstrip().split())) for _ in range(k)]
sys.stdout.write(str(min_cost(n, edges)))

C++代码实现:

#include <bits/stdc++.h>
using namespace std;

struct Edge{
    int from, to, cost;
    bool operator<(const Edge& e)const{
        return cost < e.cost;
    }
};

class UnionFind{
    vector<int> parent, rank;

public:
    UnionFind(int n){
        parent.resize(n);
        rank.resize(n, 0);
        for(int i=0; i<n; ++i)
            parent[i] = i;
    }

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

    bool union_sets(int i, int j){
        int pi = find(i);
        int pj = find(j);
        if(pi == pj)
            return false;
        if(rank[pi] < rank[pj])
            swap(pi, pj);
        parent[pj] = pi;
        rank[pi] = max(rank[pi], rank[pj]+1);
        return true;
    }
};

int main(){
    int n, k;
    cin >> n >> k;

    vector<Edge> edges(k);
    for(int i=0; i<k; ++i){
        cin >> edges[i].from >> edges[i].to >> edges[i].cost;
        edges[i].from--;
        edges[i].to--;
    }
    sort(edges.begin(), edges.end());

    UnionFind uf(n);
    int mstCost = 0, numEdges = 0;
    for(Edge e: edges){
        if(uf.union_sets(e.from, e.to)){
            mstCost += e.cost;
            numEdges++;
            if(numEdges == n-1)
                break;
        }
    }

    cout << mstCost << endl;

    return 0;
}

Java代码实现:

import java.util.*;

class Edge implements Comparable<Edge>{
    int from, to, cost;

    public Edge(int from, int to, int cost){
        this.from = from;
        this.to = to;
        this.cost = cost;
    }

    @Override
    public int compareTo(Edge e){
        return this.cost - e.cost;
    }
}

class UnionFind{
    int[] parent;
    int[] rank;

    public UnionFind(int n){
        parent = new int[n];
        rank = new int[n];
        for(int i=0; i<n; ++i)
            parent[i] = i;
    }

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

    public boolean union(int i, int j){
        int pi = find(i);
        int pj = find(j);
        if(pi == pj)
            return false;
        if(rank[pi] < rank[pj]){
            int temp = pi;
            pi = pj;
            pj = temp;
        }
        parent[pj] = pi;
        rank[pi] = Math.max(rank[pi], rank[pj]+1);
        return true;
    }
}

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int n = scanner.nextInt();
        int k = scanner.nextInt();

        UnionFind uf = new UnionFind(n);
        List<Edge> edges = new ArrayList<>();
        for(int i=0; i<k; ++i){
            int u = scanner.nextInt()-1;
            int v = scanner.nextInt()-1;
            int w = scanner.nextInt();
            edges.add(new Edge(u, v, w));
        }
        Collections.sort(edges);

        int mstCost = 0, numEdges = 0;
        for(Edge e: edges){
            if(uf.union(e.from, e.to)){
                mstCost += e.cost;
                numEdges++;
                if(numEdges == n-1)
                    break;
            }
        }

        System.out.println(mstCost);
    }
}

代码提交测试结果:

在这里插入图片描述

附B站老师讲解链接,可供参考:https://www.bilibili.com/video/BV1cs4y137za/?t=551.4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/515378.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

元宇宙医疗虚拟人的功能,创造哪些新体验

虚拟数字人的出现对于精准医疗及人类健康的发展将带来不可估量的作用。通过三维可视化、3D打印、大数据及人工智能等多种数字化手段&#xff0c;在医学研究方面取得新的进展。 居家/健康&#xff1a;智能虚拟管家、家庭虚拟医生、家庭虚拟陪护员 一、虚拟数字人的医学知识普及优…

ChatGPT中文指令(Prompt)角色预设大全!让你的AI更懂你!

ChatGPT的回答总是不令人满意&#xff0c;那可能是你对AI下错了指令/提示词&#xff08;Prompt&#xff09;&#xff0c;想要ChatGPT更懂你&#xff0c;回答更精准&#xff0c;就要给它下对指令。 在国外有大佬们已经整理出一些标准的问话模板&#xff0c;直接拿来使用后&#…

在Python环境中安装配置GDAL,并演示使用GDAL读取shapefile文件

GDAL是应用广泛的空间数据处理库&#xff0c;可以处理几何、栅格数据&#xff0c;Python是一门简单易学的编程语言&#xff0c;常用来编写数据处理工具、脚本。本文讲解如何在Python环境中安装、配置、使用GDAL。本文示例中使用的GDAL版本为3.4.3 一、下载GDAL的whl包 可以通过…

ComPDFKit PDF SDK for Windows crack

ComPDFKit PDF SDK for Windows crack 增加了对新文本编辑功能的支持&#xff0c;如添加其他字体、设置粗体/斜体、复制文本样式和修改文本透明度。 增加了对新级别文档加密的支持&#xff0c;包括AES-128和AES-256。 ComPDFKit PDF SDK允许开发人员在Windows(iOS和Android平台…

C高级-day(4)-(shell数组、shell中的算数、shell中的分支语句.)

一、编写一个名为myfirstshell.sh的脚本&#xff0c;它包括以下内容。 1、包含一段注释&#xff0c;列出您的姓名、脚本的名称和编写这个脚本的目的 2、和当前用户说“hello 用户名” 3、显示您的机器名 hostname 4、显示上一级目录中的所有文件的列表 5、显示变量PATH和H…

C/C++中程序数据的分类与内存分布,C++内存管理方式之new / delete 操作符与malloc / free的区别

TIPS const修饰数据类型并不会影响它在内存当中某个区域的存储位置&#xff0c;比方说原先是在栈区上面的&#xff0c;然后用const修饰了一下&#xff0c;并不就是说你现在已经变到静态区里面去了&#xff0c;你还是在栈上面指针与指针之间的等号赋值也需要考虑到权限的放大与…

利用Python程序生成字符画 让男大学生们洗脑的挖呀挖呀挖

源码地址 原教程在这里 演示效果&#xff1a;&#xff08;有点虚&#xff09; 利用Python程序生成字符画 让男大学生们洗脑的挖呀挖呀挖 使用教程&#xff08;源码在文章最后&#xff09; 打开pyhton编译器安装opencv和Pillow库把要进行字符串化的视频命名为input.mp4&#…

nginx: 配置https证书,wss证书

作用&#xff1a;SSL证书卸载 1、制作证书 openssl genrsa -des3 -out server.key 2048 openssl req -new -key server.key -out server.csr openssl rsa -in server.key -out server.key openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt …

windows 通过bat一键Android手机截图

首先资源需要5积分链接如下&#xff1a; https://download.csdn.net/download/weixin_38287114/87774870?spm1001.2014.3001.5501 使用范围&#xff1a; 有一台电脑是window系统&#xff0c;电脑安装配置了adb 有一台手机&#xff0c;打开了usb调试 你想截图的软件没有usb…

ArrayList 和 LinkedList 之间应该怎么选择?

Joshua Bloch&#xff1a;我写了 LinkedList&#xff0c;但我自己都不用&#xff01; 对&#xff0c;Joshua Bloch 就是 LinkedList 的作者&#xff01; 如果你真信了作者的话&#xff0c;那就真的大错特错了&#xff0c;LinkedList 虽然用的没有 ArrayList 多&#xff0c;但使…

高性能存储SIG月度动态:EROFS支持直接索引容器镜像tar包,io_uring将支持并优化NVMe直通

高性能存储 SIG&#xff08;Special Interest Group&#xff09;目标&#xff1a;存储领域的发展历程&#xff0c;本质上是存储介质与软件栈相互促进发展的过程。高性能存储 SIG 致力于存储栈性能挖掘&#xff0c;当前主要聚焦内核 io_uring 技术优化异步 IO 性能&#xff0c;使…

bugku——变量1

拿到题目后是一串PHP代码&#xff0c;给到提示是flag在变量中&#xff0c;接下来进行代码审计 error_reporting(0)&#xff1a;关闭错误报告 include “flag1.php”:包含flag1.php文件 highlight_file(_file_)&#xff1a;页面进行语法高亮显示 isset($_GET[‘args’])&#xf…

AI模型推理(4)—— 认识ServingRuntime

参考&#xff1a; Serving Runtimes - KServe Documentation Website 模型推理服务化&#xff1a;如何基于Triton开发自己的推理引擎&#xff1f; - 知乎 GitHub - openai/triton: Development repository for the Triton language and compiler 前言 ServingRuntime&#…

Qt quick基础3(基础动画,包含旋转动画、串行并行动画及其嵌套)

Qt quick基础3&#xff08;基础动画&#xff09; 目录 Qt quick基础3&#xff08;基础动画&#xff09;前言前期准备工作Animation on property 元素加载后自动运行动画Behavior on property 当元素值改变后运行动画Standalone Animation 单独动画旋转动画分组动画串行动画并行…

干货 | 科研决策怎么做?四个步骤一招解决!

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ 又是给大家带来满满干货的一天&#xff0c;今天要给大家介绍的是狐少侠对于科学决策的四个步骤的详细解读&#xff01; 最近&#xff0c;有读者问了我几个关于决策的问题&#xff1a;要不要…

ubuntu22.04 编译安装 Kate 编辑器

ubuntu22.04 编译安装 Kate 编辑器 文章目录 ubuntu22.04 编译安装 Kate 编辑器0x0 目的0x1 在 Ubuntu 22.04 编译安装 Kate0x11 Download dependencies0x12 Build kate and kwrite0x13 Setup paths for binary and shared libraries0x14 Misc trials 0x2 配置 Kate渲染空白字符…

R语言 | 数据分析与处理

目录 一、随机抽样 1.1 将随机抽样应用于扑克牌 1.2 种子值 ​1.3 模拟骰子 1.4 比重的设置 二、再谈向量数据的抽取——以islands为实例 三、数据框数据的抽取——重复值的处理 ​3.1 重复值的搜索 3.2 which()函数 3.3 抽取数据是去除重复值 四、数据框数据的抽取…

Linux命令·scp

scp是secure copy的简写&#xff0c;用于在Linux下进行远程拷贝文件的命令&#xff0c;和它类似的命令有cp&#xff0c;不过cp只是在本机进行拷贝不能跨服务器&#xff0c;而且scp传输是加密的。可能会稍微影响一下速度。当你服务器硬盘变为只读 read only system时&#xff0c…

【深度学习】第一门课 神经网络和深度学习 Week 2 神经网络基础

2.1 二元分类 前言 第二周的主题是学习神经网络的基础知识。 实现神经网络需要用到一些重要的技术和技巧&#xff0c;比如怎样处理包含大量样本的训练集。 在神经网络的计算中&#xff0c;还会有前向暂停、前向传播、反向暂停和反向传播等步骤&#xff0c;本周会对它们进行…

面试一个6年经验测试员:一年经验硬生生用了六年....

在众多面试中&#xff0c;对于那个工作了6年的面试者&#xff0c;我印象很深刻&#xff0c;因为最开始拿到简历的时候&#xff0c;我一摸:"这简历&#xff0c;好厚啊&#xff01;"再一看&#xff0c;工作6年。 于是我去找了我的领导&#xff0c;我说:“这人我应该没…