每周题解:繁忙的都市

题目链接

繁忙的都市

题目描述

城市 C 是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造。城市 C 的道路是这样分布的:城市中有 n n n 个交叉路口,有些交叉路口之间有道路相连,两个交叉路口之间最多有一条道路相连接。这些道路是双向的,且把所有的交叉路口直接或间接的连接起来了。每条道路都有一个分值,分值越小表示这个道路越繁忙,越需要进行改造。但是市政府的资金有限,市长希望进行改造的道路越少越好,于是他提出下面的要求:

  1. 改造的那些道路能够把所有的交叉路口直接或间接的连通起来。
  2. 在满足要求 1 的情况下,改造的道路尽量少。
  3. 在满足要求 1、2 的情况下,改造的那些道路中分值最大的道路分值尽量小。

任务:作为市规划局的你,应当作出最佳的决策,选择哪些道路应当被修建。

输入格式

第一行有两个整数 n , m n,m n,m 表示城市有 n n n 个交叉路口, m m m 条道路。

接下来 m m m 行是对每条道路的描述, u , v , c u, v, c u,v,c 表示交叉路口 u u u v v v 之间有道路相连,分值为 c c c

输出格式

两个整数 s , m a x s, \mathit{max} s,max,表示你选出了几条道路,分值最大的那条道路的分值是多少。

样例 #1

样例输入 #1

4 5
1 2 3
1 4 5
2 4 7
2 3 6
3 4 8

样例输出 #1

3 6

提示

数据范围及约定

对于全部数据,满足 1 ≤ n ≤ 300 1\le n\le 300 1n300 1 ≤ c ≤ 1 0 4 1\le c\le 10^4 1c104 1 ≤ m ≤ 8000 1 \le m \le 8000 1m8000

算法思想

根据题目描述,道路改造后所有交叉路口依然保持连通,改造的道路尽量少,并且改造的那些道路中分值最大的道路分值尽量小。

为了保证改造后依旧是连通的,可以在图中生成一棵树,也就是选择 n − 1 n-1 n1条边使图依然保持连通,并且此时改造的道路最少。

那么如何保证分值最大的那条道路分值尽量小呢?这里有两种思路。

二分答案

求分值最大的那条道路分值最小,通常可以用二分答案来解决。基本思想是:

  • 对所有边按边权从小到大排序
  • 1 ∼ m 1\sim m 1m中选择中间位置 m i d mid mid,检查用 1 ∼ m i d 1\sim mid 1mid的所有边能否将 n n n个交叉路口连接起来
    • 如果能够连通,再到 1 ∼ m i d 1\sim mid 1mid查找答案
    • 否则不能连通,再到 m i d + 1 ∼ m mid+1\sim m mid+1m查找答案

检查过程中,可以使用并查集的思想来统计连通块中点的个数,判断是否通过若干条边将 n n n个点连接起来。

时间复杂度

将所有边排序的排序时间复杂度为 O ( m l o g m ) O(mlogm) O(mlogm),二分答案的时间复杂度为 O ( m l o g m ) O(mlogm) O(mlogm)

代码实现

#include <bits/stdc++.h>
using namespace std;
const int M = 16005;
struct E {int a, b, c;bool operator < (const E &e) const{return c < e.c;}
}e[M];
int n, m, p[M];
int find(int x)
{if(x != p[x]) p[x] = find(p[x]);return p[x];
}
bool check(int mid)
{for(int i = 1; i <= mid; i ++) p[i] = i; //并查集初始化int cnt = 1; //连通块中的点数初始化为1for(int i = 1; i <= mid; i ++){int a = e[i].a, b = e[i].b, c = e[i].c;a = find(a), b = find(b);if(a != b) //如果a和b不连通,则将它们连通起来{p[a] = b;cnt ++; //连通块的点数+1}}return cnt == n; //如果连通块中的点数为n,说明所有点连通起来了
}
int main()
{cin >> n >> m;for(int i = 1; i <= m; i ++){int a, b, c;cin >> a >> b >> c;e[i] = {a, b, c};}sort(e + 1, e + m + 1);int L = 1, R = m;while(L < R){int mid = (L + R) / 2;if(check(mid)) R = mid;else L = mid + 1;}cout << n - 1 << " " << e[L].c << endl;return 0;
}

最小生成树

与一般意义的(所有边权和最小的)最小生成树不同,本题中要求的是最大的边权最小的最小生成树。考虑使用Kruskal算法求最小生成树的基本思想:

  • 将所有边按边权从小到大排序
  • 从小到大依次枚举每条边, a , b , c a, b, c a,b,c,其中边权为 c c c
    • 如果 a a a b b b已经连通,那么直接跳过
    • 如果 a a a b b b不连通,那么就将当前边选出来,将 a a a b b b纳入一个连通块
  • 当所有点都在同一个连通块时,最小生成树建立完毕。

在这个过程中,由于边权是按从小到大排序的,因此连通最后一个点所使用的边,就是生成树中边权最大的边。

由此可见,Kruskal 算法求出的最小生成树,不但总权值和最小,而且最大边的边权一定是所有的生成树最大边中最小的。

时间复杂度

将所有边排序的排序时间复杂度为 O ( m l o g m ) O(mlogm) O(mlogm),Kruskal时间复杂度为 O ( m ) O(m) O(m)

代码实现

#include <bits/stdc++.h>
using namespace std;
const int M = 16005;
struct E {int a, b, c;bool operator < (const E &e) const{return c < e.c;}
}e[M];
int n, m, p[M];
int find(int x)
{if(x != p[x]) p[x] = find(p[x]);return p[x];
}int main()
{cin >> n >> m;for(int i = 1; i <= m; i ++){int a, b, c;cin >> a >> b >> c;e[i] = {a, b, c};}sort(e + 1, e + m + 1);for(int i = 1; i <= m; i ++) p[i] = i;int ans;for(int i = 1; i <= m; i ++){int a = find(e[i].a), b = find(e[i].b), c = e[i].c;if(a != b) {p[a] = b;ans = c;}}cout << n - 1 << " " << ans << endl;return 0;
}

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

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

相关文章

5月26(信息差)

&#x1f30d; 珠峰登顶“堵车”后冰架断裂 5人坠崖 2人没爬上来&#xff01; 珠峰登顶“堵车”后冰架断裂 5人坠崖 2人没爬上来&#xff01; &#x1f384; Windows 11 Beta 22635.3646 预览版发布&#xff1a;中国大陆地区新增“微软电脑管家”应用 ✨ 成都限购解除即将满…

[图解]产品经理-竞赛题解析:阿布思考法和EA

1 00:00:00,410 --> 00:00:02,330 今天我们来说一道 2 00:00:02,610 --> 00:00:04,690 前些天出的一道竞赛题 3 00:00:07,250 --> 00:00:09,310 怎么样用阿布思考法 4 00:00:09,320 --> 00:00:10,540 来改进EA 5 00:00:11,690 --> 00:00:12,620 题目是这样的…

简述 v-model 双向绑定的原理是什么?

v-model 是 Vue.js 中用于实现表单输入和应用状态&#xff08;即数据&#xff09;之间双向绑定的指令。其原理可以概括如下&#xff1a; 基本思想&#xff1a; v-model 是 v-bind 和 v-on 的语法糖&#xff0c;它结合了输入元素的 value 属性和 input 事件。当输入元素的值发生…

Kivy 项目51斩百词 5

MRWord\pages\infopage\info.py def read_random_word(self) def read_random_word(self):"""随机读取一条数据"""sql "SELECT * FROM word WHERE id (SELECT word_id FROM today ORDER BY RANDOM() limit 1)"rows select_data(sq…

Django 里html模板

Django 提供两种方式让程序员自定义html模板。 第一种方法 在项目文件夹里的urls.py进行添加 修改代码如下 from django.contrib import admin from django.urls import path from app01 import views # 得添加这行urlpatterns [path(xxx/, views.home), # 添加这行path(…

Java中print,println,printf的功能以及区别

在Java中&#xff0c;System.out.print, System.out.println, 和 System.out.printf 都是用于在控制台输出的方法&#xff0c;但它们在使用和功能上有所不同。 System.out.print: * 功能&#xff1a;将指定的内容输出到控制台&#xff0c;但不换行。 * 示例&#xff1a;Sy…

TXT文本编辑器:一键提取,多关键字匹配,内容尽在掌控!

在浩如烟海的文档中&#xff0c;寻找关键信息往往是一项繁琐而耗时的任务。你是否曾经为了查找某个关键字而翻遍了整个文件夹&#xff0c;却仍然一无所获&#xff1f;现在&#xff0c;有了TXT文本编辑器&#xff0c;这一切都将变得轻松而高效 这款软件以其简洁明了的操作界面和…

Flutter 中的 FittedBox 小部件:全面指南

Flutter 中的 FittedBox 小部件&#xff1a;全面指南 在Flutter的丰富布局小部件中&#xff0c;FittedBox扮演着一个独特而重要的角色。它是一个灵活的组件&#xff0c;用于将子组件的大小和位置适应到给定的约束条件中。本文将提供FittedBox的全面指南&#xff0c;帮助你了解…

C#9特性整理(部分)

1. 实例化类型推断&#xff08;Target-typed new&#xff09; 我们会使用 new 关键字来实例化&#xff0c;但在部分字段和属性声明的时候&#xff0c;这些类型已经是在旁边给出&#xff0c;且不能使用 var 代替的。因此&#xff0c;我们必须这么写&#xff1a; public Person…

最近5星好评的华为的书《常变与长青》

常变与长青 (豆瓣) 作者简介 郭平&#xff0c;1988年加入华为&#xff0c;历任产品开发部项目经理、供应链总经理、总裁办主任、管理工程部总裁、企业发展部总裁、终端公司董事长兼总裁、公司轮值CEO、财经委员会主任、公司副董事长、轮值董事长等职务&#xff0c;现任公…

微信小程序毕业设计-学生知识成果展示与交流系统项目开发实战(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

接口自动化核心模块Requests详解(二)

一、概述 使用requests进行接口测试时&#xff0c;主要使用get 和post两种方式,两种请求方式的传参模式和方法是完全不一样的 二、传参实战 2.1 post传参的数据格式 使用post进行传参时&#xff0c;有三种数据格式&#xff0c;data(键值对的字典)&#xff0c;json(有嵌套的…

Keyshot v11 解锁版安装教程 (3D光线追踪与全域光渲染程序)

前言 keyshot是一款实时渲染模式的软件。实时渲染是目前比较流行的一种渲染方式&#xff0c;优点是快速。调节的材质&#xff0c;灯光修改&#xff0c;光影变化等修改的各种参数结果&#xff0c;所见即所得&#xff0c;意思是你在软件操作界面看到的&#xff0c;就是最终的结果…

props配置项

src/App.vue: <template><div><Student name"JOJO" sex"男酮" :age"20" /></div> </template><script>import Student from ./components/Student.vueexport default {name:App,components: { Student },}…

绘制t-SNE图

什么是t-SNE图&#xff1f; 如下图&#xff0c;下图来源于论文Contrastive Clustering 一般用于分类问题/对比学习。 作用&#xff1f; 体现出经过层层训练&#xff0c;类内越来越紧密&#xff0c;类间差异越来越大&#xff1b;或者也可以做消融可视化。 怎么画&#xff1f…

vim操作手册

vim分为插入模式、命令模式、底行模式。 插入模式&#xff1a;编辑模式 命令模式&#xff1a;允许使用者通过命令&#xff0c;来进行文本的编辑控制 底行模式&#xff1a;用来进行让vim进行包括但不限于shell进行交互 w&#xff1a;保存 wq&am…

Actor-critic学习笔记-李宏毅

Policy Gradient review ∇ R ‾ θ 1 N ∑ n 1 N ∑ t 1 T n ( ∑ t ′ t T n γ t ′ − t r t ′ n − b ) ∇ log ⁡ p θ ( a t n ∣ s t n ) \nabla \overline{R}_\theta \frac{1}{N}\sum_{n 1}^{N}\sum_{t 1}^{T_n}(\sum_{tt}^{T_n}\gamma^{t-t}r_{t}^n-b)\nabl…

提高软件团队开发速度和质量的策略

在现代软件开发中&#xff0c;提高开发速度和质量是每个团队追求的目标。高效的开发流程不仅能缩短产品的上市时间&#xff0c;还能确保软件的稳定性和可靠性。本文将探讨提高软件团队开发速度和质量的各种策略&#xff0c;包括技术、流程、团队文化等方面。 一、采用敏捷开发…