2024年4月12日饿了么春招实习试题【第三题】-题目+题解+在线评测,2024.4.12,饿了么机试【Kruskal 算法, 最小生成树】

2024年4月12日饿了么春招实习试题【第三题】-题目+题解+在线评测,2024.4.12,饿了么机试

  • 🏩题目一描述:
    • 样例1
    • 样例2
    • 解题思路一:[Kruskal 算法](https://baike.baidu.com/item/%E5%85%8B%E9%B2%81%E6%96%AF%E5%8D%A1%E5%B0%94%E7%AE%97%E6%B3%95/4455899?fr=ge_ala) 最小生成树(MST,Minimum Spanning Tree)
    • 解题思路二:
    • 解题思路三:java, c++

🏩题目一描述:

K小姐计划去 n 个城市旅行。这些城市之间有 m 条双向道路相连,每条道路都有一个美景值 w 。

K小姐希望选择一些道路,使得最终所有城市恰好被分成两个连通块。她可以获得所有被选择的道路的美景值之和。

现在K小姐想知道,她能获得的最大的美景值是多少?如果初始时这些城市已经形成了两个或更多的连通块,则输出 − 1 。

输入格式
第一行包含两个正整数 n 和 m ,分别表示城市的数量和道路的数量。

接下来 m 行,每行包含三个正整数 u, v, w,表示城市 u 和城市 v 之间有一条美景值为 w 的道路。

输出格式
输出一个整数,表示K小姐能获得的最大美景值。如果初始时这些城市已经形成了两个或更多的连通块,则输出 − 1。

数据范围

  • 2 ≤ n ≤ 1 0 5 2 \leq n \leq 10^5 2n105
  • 0 ≤ m ≤ 1 0 5 0 \leq m \leq 10^5 0m105
  • 1 ≤ u , v ≤ n 1 \leq u, v \leq n 1u,vn
  • 1 ≤ w ≤ 1 0 9 1 \leq w \leq 10^9 1w109

样例1

输入

3 3
1 2 4
2 3 3
1 3 2

输出

7

说明

删除前两条边即可,这样有两个连通块:节点1和节在3的连通块,节点2自己为一个连通块。

样例2

输入

4 2
1 2 4
3 4 3

输出

0

说明

初始即为两个连通块,无法删除任何边

OJ链接:
https://codefun2000.com/p/P1818

解题思路一:Kruskal 算法 最小生成树(MST,Minimum Spanning Tree)

cnt = 原图节点的数量n - Kruskal 算法构建的边的数量 = 最终剩下的连通分量的个数
maxv 记录构建连通分量时,边权重的最大值
total 是所有边的权重和

最终cnt(连通分量)有三种情况

  1. cnt == 1。说明只有一个连通分量,返回total(构建完最小生成树的剩下的权重)和maxv(最小生成树中的最大权重边)的和!
  2. cnt == 2。说明有两个连通分量,直接返回total(构建完两个最小生成树的剩下的权重)
  3. cnt > 2。说明连通分量大于3,直接返回-1
n, m = map(int, input().split())
total = 0
roads = []
def find(p, x): # 定义一个查找并查集中元素根节点的函数。它实现了路径压缩,使查询更高效。
    if p[x] != x:
        p[x] = find(p, p[x])
    return p[x]
for _ in range(m):
    u, v, w = map(int, input().split())
    total += w
    roads.append((u, v, w))
roads.sort(key = lambda x: x[2]) # 按边的权重对边进行排序,这是Kruskal算法构建MST的关键步骤。
p = list(range(n+1)) # 并查集 初始化并查集,每个节点的父节点初始化为其自身。
cnt = n
maxv = 0
for u, v, w in roads:
    u = find(p, u)
    v = find(p, v)
    if u != v: # 遍历按权重排序的边,使用并查集判断是否形成环,不形成环则加入MST并更新相关变量。
        p[u] = v # 加入并查集
        total -= w
        cnt -= 1
        maxv = max(maxv, w)

if cnt == 1:
    print(maxv + total)
elif cnt == 2:
    print(total)
else:
    print(-1)

时间复杂度:O(mlogm)
空间复杂度:O(n)

解题思路二:

在这里插入图片描述

import sys
input = lambda: sys.stdin.readline().strip()
sys.setrecursionlimit(10**6)

def find(p, x):
    if p[x] != x:
        p[x] = find(p, p[x])
    return p[x]

def main():
    n, m = map(int, input().split())
    roads = []
    total = 0
    for _ in range(m):
        u, v, w = map(int, input().split())
        roads.append((u, v, w))
        total += w
    
    roads.sort(key=lambda x: x[2])
    
    p = list(range(n + 1))
    cnt = n
    maxv = 0
    for u, v, w in roads:
        u = find(p, u)
        v = find(p, v)
        if u != v:
            p[u] = v
            total -= w
            cnt -= 1
            maxv = max(maxv, w)
    
    if cnt == 1:
        print(total + maxv)
    elif cnt == 2:
        print(total)
    else:
        print(-1)

if __name__ == "__main__":
    main()

时间复杂度:O(mlogm)
空间复杂度:O(n)

解题思路三:java, c++

import java.io.*;
import java.util.*;

public class Main {
    static int[] p;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = br.readLine().split(" ");
        int n = Integer.parseInt(input[0]);
        int m = Integer.parseInt(input[1]);
        
        int[][] roads = new int[m][3];
        long total = 0;
        for (int i = 0; i < m; i++) {
            input = br.readLine().split(" ");
            roads[i][0] = Integer.parseInt(input[0]);
            roads[i][1] = Integer.parseInt(input[1]);
            roads[i][2] = Integer.parseInt(input[2]);
            total += roads[i][2];
        }
        
        Arrays.sort(roads, (a, b) -> a[2] - b[2]);
        
        p = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            p[i] = i;
        }
        
        int cnt = n;
        int maxv = 0;
        for (int[] road : roads) {
            int u = find(road[0]);
            int v = find(road[1]);
            if (u != v) {
                p[u] = v;
                total -= road[2];
                cnt--;
                maxv = Math.max(maxv, road[2]);
            }
        }
        
        if (cnt == 1) {
            System.out.println(total + maxv);
        } else if (cnt == 2) {
            System.out.println(total);
        } else {
            System.out.println(-1);
        }
    }
    
    static int find(int x) {
        if (p[x] != x) {
            p[x] = find(p[x]);
        }
        return p[x];
    }
}

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> p;

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

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    
    vector<vector<int>> roads(m, vector<int>(3));
    long long total = 0;
    for (int i = 0; i < m; i++) {
        cin >> roads[i][0] >> roads[i][1] >> roads[i][2];
        total += roads[i][2];
    }
    
    sort(roads.begin(), roads.end(), [](const vector<int>& a, const vector<int>& b) {
        return a[2] < b[2];
    });
    
    p.resize(n + 1);
    for (int i = 1; i <= n; i++) {
        p[i] = i;
    }
    
    int cnt = n;
    int maxv = 0;
    for (auto& road : roads) {
        int u = find(road[0]);
        int v = find(road[1]);
        if (u != v) {
            p[u] = v;
            total -= road[2];
            cnt--;
            maxv = max(maxv, road[2]);
        }
    }
    
    if (cnt == 1) {
        cout << total + maxv << '\n';
    } else if (cnt == 2) {
        cout << total << '\n';
    } else {
        cout << -1 << '\n';
    }
    
    return 0;
}

时间复杂度:O(mlogm)
空间复杂度:O(n)


创作不易,观众老爷们请留步… 动起可爱的小手,点个赞再走呗 (๑◕ܫ←๑)
欢迎大家关注笔者,你的关注是我持续更博的最大动力


原创文章,转载告知,盗版必究



在这里插入图片描述


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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

牛客网Java实战项目--仿牛客网社区的学习笔记

仿牛客网社区的学习笔记 1. 项目环境搭建1.1 开发社区首页 2.开发社区登录模块2.1 发送邮件2.2 开发注册功能2.3 会话管理2.4 生成验证码2.5 开发登录、退出功能2.6 显示登录信息 4 Redis实现点赞关注4.1 Spring整合Redis访问Redis的方法&#xff1a; 4.2 Redis实现点赞4.2.1 点…

Git系列:git merge 使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

Redis基础面试知识点(1)

相比于C字符串&#xff0c;SDS的优势&#xff1a; O(1)获取字符串的长度不会缓冲区溢出减少修改字符串时所需的内存重新分配的次数&#xff08;空间预分配、惰性空间释放&#xff09;二进制API安全&#xff08;通过len获取长度&#xff09;兼容部分C字符串函数 Redis hash策略…

SpringAMQP Work Queue 工作队列

消息模型: 代码模拟: 相较于之前的基础队列&#xff0c;该队列新增了消费者 不再是一个&#xff0c;所以我们通过代码模拟出两个consumer消费者。在原来的消费者类里写两个方法 其中消费者1效率高 消费者2效率低 RabbitListener(queues "simple.queue")public voi…

机器学习算法应用——CART决策树

CART决策树&#xff08;4-2&#xff09; CART&#xff08;Classification and Regression Trees&#xff09;决策树是一种常用的机器学习算法&#xff0c;它既可以用于分类问题&#xff0c;也可以用于回归问题。CART决策树的主要原理是通过递归地将数据集划分为两个子集来构建决…

【nodejs 命令行交互神器 - inquirer.js】

需求 大家在开发时&#xff0c;有时需要从命令行读取用户的输入&#xff0c;或者让用户选择。在nodejs中&#xff0c;这个怎么实现? 原生实现 ❌ process.stdin.setEncoding(utf8);process.stdin.on(readable, () > {let chunk;// 使用循环确保我们读取所有的可用输入wh…

【C++算法】队列相关经典算法题

1. N叉树的层序遍历 首先我们遇到这个题目&#xff0c;没有任何思路&#xff0c;我们就可以来模拟一下层序的流程&#xff0c;首先我们肯定是访问根节点1&#xff0c;访问之后呢就是访问下一层的最左节点3&#xff0c;此时第一层的节点1已经访问过了就可以不要了&#xff0c;然…

词令蚂蚁新村今日答案:微信小程序怎么查看蚂蚁新村今天问题的正确答案?

微信小程序怎么查看蚂蚁新村今天问题的正确答案&#xff1f; 1、打开微信&#xff0c;点击搜索框&#xff1b; 2、打开搜索页面&#xff0c;选择小程序搜索&#xff1b; 3、在搜索框&#xff0c;输入词令搜索点击进入词令微信小程序&#xff1b; 4、打开词令微信小程序关键词口…

每日10亿数据的日志分析系统OOM

背景 一个每日10亿数据的日志清洗系统&#xff0c;主要工作就是从消息队列中消费各种各样的日志&#xff0c;然后对日志进行清洗&#xff0c;例如&#xff1a;用户敏感信息(姓名、手机号、身份证)进行脱敏处理,然后把清理完的数据交付给其他系统使用。 我们项目中&#xff0c;…

设计模式2——原则篇:依赖倒转原则、单一职责原则、合成|聚合复用原则、开放-封闭原则、迪米特法则、里氏代换原则

设计模式2——设计原则篇 目录 一、依赖倒转原则 二、单一职责原则&#xff08;SRP&#xff09; 三、合成|聚合复用原则&#xff08;CARP&#xff09; 四、开放-封闭原则 五、迪米特法则&#xff08;LoD&#xff09; 六、里氏代换原则 七、接口隔离原则 八、总结 一、依赖…

《2024年AI安全报告》:AIML工具使用量飙升594.82%

人工智能&#xff08;AI&#xff09;不仅仅是一种开拓性的创新技术&#xff0c;甚至已经成为一种常态&#xff0c;企业正在工程、IT营销、财务、客户服务等领域迅速采用AI和机器学习&#xff08;ML&#xff09;工具。但与此同时&#xff0c;他们必须平衡AI工具带来的诸多风险&a…

JWT深入浅出

文章目录 JWT深入浅出1.JWT是什么2.为什么选JWT2.1 传统Session认证2.2 JWT认证 3.JWT怎么用4. jwt绝对安全吗&#xff1f; JWT深入浅出 1.JWT是什么 JWT&#xff08;JSON Web Token&#xff09;是一种用于在网络应用间传递信息的开放标准&#xff0c;通常用于身份认证和非敏…

24寸2K显示器 - HKC G24H2

&#x1f525;&#x1f5a5;️ 嘿&#xff0c;大家好&#xff01;今天&#xff0c;我要给大家介绍一款超棒的显示器——HKCG24H2&#xff01;这款显示器可是个全能选手&#xff0c;无论你是工作狂人还是游戏迷&#xff0c;它都能满足你的需求&#xff01; &#x1f60e;&#x…

传输层之 UDP 协议

UDP协议端格式 教科书上的&#xff1a; 16位UDP长度&#xff0c;表示整个数据报&#xff08;UDP首部UDP数据&#xff09;的最大长度&#xff0c;描述了这个数据报多长&#xff1b; 实际上的&#xff1a; UDP 会把载荷数据&#xff0c;就是通过 UDP Socket&#xff0c;即 sen…

PyQt5批量生成Checkbox及批量检查Checkbox的勾选状态

批量生成Checkbox并添加到TableWidget中 for i in range(10):checkbox_i QCheckBox(fCheckbox_{i}) # 生成Checkbox并命名为Checkbox_iself.ui_1.tableWidget_1.setCellWidget(i,1,checkbox_i) 批量检查勾选状态 # 批量生成Checkbox并存入列表 list_Checkbox_1 [] for …

vue3专栏项目 -- 三、使用vue-router 和 vuex(下)

一、添加columnDetail 页面 首页有专栏列表&#xff08;ColumnList组件&#xff09;&#xff0c;专栏列表中有很多专栏&#xff0c;然后点击某个专栏就进入专栏详情页&#xff08;ColumnDetail组件&#xff09;&#xff0c;专栏详情页中有很多文章&#xff0c;点击某个文章就进…

uni-segmented-control插件使用

dcloud插件市场 前端/uniapp 1.HBuildX打开目标项目 2.进入dcloud插件市场下载目标插件 3.看到如下提示(已经可以在目标项目中使用插件啦) 4.项目正式使用

物联网平台之单体架构

介绍本文主要介绍平台的单体架构&#xff0c;包括各个组件之间的数据流描述以及所做的一些架构选择。在单体架构模式下&#xff0c;所有 ThingsKit 组件都在单个 Java 虚拟机 (JVM) 中启动&#xff0c;并共享相同的操作系统资源。由于 ThingsKit 是用 Java 编写的&#xff0c;因…

springcloud alibaba微服务框架涉及的技术

一、微服务架构中核心模块及其使用技术总览 二、各模块详细说明 1、注册中心 该模块主要功能为 自动提供服务的注册与发现&#xff0c;集中式管理服务&#xff0c;让 服务调用端发现服务&#xff0c;让服务提供端注册服务&#xff0c;倘若没有注册中心&#xff0c;那客户端就…

JUC下的BlockingQueue详解

BlockingQueue是Java并发包(java.util.concurrent)中提供的一个接口&#xff0c;它扩展了Queue接口&#xff0c;增加了阻塞功能。这意味着当队列满时尝试入队操作&#xff0c;或者队列空时尝试出队操作&#xff0c;线程会进入等待状态&#xff0c;直到队列状态允许操作继续。这…