经典编程题:服务器广播
题目描述:
服务器连接方式包括直接相连,间接连接。A 和 B 直接连接,B 和 C 直接连接,则 A 和 C 间接连接。直接连接和间接连接都可以发送广播。
给出一个 N*N 数组,代表 N 个服务器,matrix[i][j]==1,则代表 i 和 j 直接连接;
不等于 1 时,代表 i 和 j 不直接连接。
matrix[i][i]==1,即自己和自己直接连接。matrix[i][j]==matrix[j][i]。
计算初始需要给几台服务器广播,才可以使每个服务器都收到广播。
输入描述
输入为N行,每行有N个数字,为0或1,由空格分隔,构成N*N的数组,N的范围为 1<=N<=50
输出描述
输出一个数字,为需要广播的服务器数量
示例 1:
输入
1 0 0
0 1 0
0 0 1
输出
3
说明
3台服务器互不连接,所以需要分别广播这3台服务器
示例 2:
输入
1 1
1 1
输出
1
说明
2台服务器相互连接,所以只需要广播其中一台服务器。
要解决这个问题,我们需要确定网络中有多少个互不连接的子网络(即连通分量)。每个连通分量中的服务器可以通过直接或间接连接互相通信,因此对于每个连通分量,只需从其中一台服务器广播即可覆盖整个子网络。
解题步骤:
-
输入解析:
- 首先读取所有的输入行,并将其转换为一个二维列表(矩阵)。
- 确定
N
的值,即服务器的数量,等于输入的行数。
-
图的表示:
- 将服务器之间的连接关系表示为一个无向图,使用邻接矩阵的形式。
-
连通分量的计算:
- 使用深度优先搜索(DFS)或广度优先搜索(BFS)来遍历图,计算有多少个连通分量。
- 每找到一个新的连通分量,广播次数加一。
-
输出结果:
- 最终输出连通分量的数量,即所需的最少广播次数。
下面是使用 Python 实现的代码:
def count_broadcasts(matrix):N = len(matrix)visited = [False] * Ncount = 0def dfs(node):for neighbor in range(N):if matrix[node][neighbor] == 1 and not visited[neighbor]:visited[neighbor] = Truedfs(neighbor)for i in range(N):if not visited[i]:visited[i] = Truedfs(i)count += 1return countdef main():import sysinput_lines = sys.stdin.read().strip().split('\n')matrix = []for line in input_lines:if line.strip() == '':continuerow = list(map(int, line.strip().split()))matrix.append(row)# Validate that it's an N x N matrixN = len(matrix)for row in matrix:if len(row) != N:print("输入的矩阵不是 N*N 的格式。")returnresult = count_broadcasts(matrix)print(result)if __name__ == "__main__":main()
代码说明:
-
count_broadcasts
函数:- 接受一个二维列表
matrix
作为输入,表示服务器之间的连接关系。 - 使用 DFS 来遍历每个连通分量,
count
用于记录连通分量的数量。
- 接受一个二维列表
-
main
函数:- 从标准输入读取所有输入行,并将其转换为整数矩阵。
- 检查输入是否为一个有效的 N×N 矩阵。
- 调用
count_broadcasts
函数并输出结果。
示例运行:
示例 1:
输入:
1 0 0
0 1 0
0 0 1输出:
3
示例 2:
输入:
1 1
1 1输出:
1
使用方法:
将上述代码保存为一个 Python 脚本,例如 broadcast.py
,然后在命令行中运行:
python broadcast.py
然后输入矩阵数据,按 Ctrl+D
(或在 Windows 上按 Ctrl+Z
然后回车)结束输入,程序将输出所需的广播次数。
在给定的解决方案中,我们使用深度优先搜索(DFS)来计算图中的连通分量数量,从而确定需要广播的服务器数量。下面详细分析该算法的时间复杂度和空间复杂度。
时间复杂度(Time Complexity)
-
输入解析:
- 读取并解析输入的 N×N 矩阵需要遍历所有的元素,因此时间复杂度为 O(N²)。
-
DFS 遍历:
- 在最坏情况下,图是一个完全连通的图(每个服务器都直接连接到其他所有服务器),DFS 需要遍历所有的边和节点。
- 对于一个 N 个节点的无向图,边的数量最多为 N(N-1)/2,因此 DFS 的时间复杂度为 O(N²)。
-
整体时间复杂度:
- 输入解析和 DFS 遍历都是 O(N²),因此整体时间复杂度为 O(N²)。
空间复杂度(Space Complexity)
-
存储矩阵:
- 输入的 N×N 矩阵需要 O(N²) 的空间来存储。
-
辅助数据结构:
visited
数组:用于记录每个服务器是否已被访问,空间复杂度为 O(N)。- 递归调用栈(在最坏情况下,递归深度为 N):空间复杂度为 O(N)。
-
整体空间复杂度:
- 主导因素是存储矩阵的 O(N²),因此整体空间复杂度为 O(N²)。
总结
- 时间复杂度: O(N²)
- 空间复杂度: O(N²)
这种复杂度在 N 的范围内(1 ≤ N ≤ 50)是可以接受的,因为 N 的上限相对较小,不会导致性能问题。
进一步优化
虽然当前的时间和空间复杂度已经适用于题目给定的约束,但如果 N 的范围更大,可以考虑以下优化:
-
使用邻接表表示图:
- 对于稀疏图,邻接表可以减少空间复杂度到 O(N + E),其中 E 是边的数量。
- DFS 的时间复杂度也可以降低到 O(N + E)。
-
使用并查集(Union-Find):
- 并查集可以高效地合并连通分量,并且几乎具有常数时间的查询和合并操作。
- 时间复杂度为 O(N² α(N)),其中 α(N) 是阿克曼函数的反函数,几乎可以看作是常数。
不过,对于当前题目中的 N 范围,这些优化并不是必要的。
使用**并查集(Union-Find)**来解决这个问题是一种高效的方法,尤其适用于处理连通性问题。并查集能够快速合并和查找集合,帮助我们确定网络中有多少个独立的连通分量,从而计算需要广播的服务器数量。
并查集简介
并查集是一种数据结构,用于跟踪元素分组情况,支持以下两种操作:
- 查找(Find): 确定某个元素属于哪个集合。
- 合并(Union): 将两个集合合并成一个。
为了优化并查集的性能,通常会使用**路径压缩(Path Compression)和按秩合并(Union by Rank)**技术。
使用并查集解决问题的步骤
-
初始化并查集:
- 每个服务器初始时都属于自己的集合。
-
遍历矩阵并执行合并操作:
- 对于矩阵中的每一对服务器
(i, j)
,如果matrix[i][j] == 1
,则将它们合并到同一个集合中。 - 由于矩阵是对称的,我们只需遍历上三角或下三角部分以避免重复处理。
- 对于矩阵中的每一对服务器
-
统计独立的集合数量:
- 最终并查集中不同的根节点数量即为需要广播的服务器数量。
Python 实现
以下是使用并查集解决该问题的 Python 代码:
class UnionFind:def __init__(self, size):# 初始化父节点数组,每个节点的父节点是自己self.parent = [i for i in range(size)]# 初始化秩数组,用于按秩合并self.rank = [1] * sizedef find(self, x):# 路径压缩:递归查找根节点,并将路径上的所有节点直接连接到根节点if self.parent[x] != x:self.parent[x] = self.find(self.parent[x])return self.parent[x]def union(self, x, y):# 查找两个元素的根节点root_x = self.find(x)root_y = self.find(y)if root_x == root_y:# 已经在同一个集合中,无需合并return# 按秩合并:将秩较小的树连接到秩较大的树下if self.rank[root_x] < self.rank[root_y]:self.parent[root_x] = root_yelif self.rank[root_x] > self.rank[root_y]:self.parent[root_y] = root_xelse:# 秩相同,任意合并,并增加新根节点的秩self.parent[root_y] = root_xself.rank[root_x] += 1def count_broadcasts_union_find(matrix):if not matrix:return 0N = len(matrix)uf = UnionFind(N)# 遍历上三角矩阵,避免重复处理for i in range(N):for j in range(i + 1, N):if matrix[i][j] == 1:uf.union(i, j)# 使用集合来统计不同的根节点unique_roots = set()for i in range(N):root = uf.find(i)unique_roots.add(root)return len(unique_roots)def main():import sysinput_lines = sys.stdin.read().strip().split('\n')matrix = []for line in input_lines:if line.strip() == '':continuerow = list(map(int, line.strip().split()))matrix.append(row)# 验证输入是否为 N x N 矩阵N = len(matrix)for row in matrix:if len(row) != N:print("输入的矩阵不是 N*N 的格式。")returnresult = count_broadcasts_union_find(matrix)print(result)if __name__ == "__main__":main()
代码说明
-
UnionFind
类:__init__
方法: 初始化父节点和秩数组。find
方法: 实现路径压缩,确保树的高度尽可能低。union
方法: 根据秩合并两个集合,确保较小的树连接到较大的树下。
-
count_broadcasts_union_find
函数:- 初始化并查集。
- 遍历上三角矩阵,如果
matrix[i][j] == 1
,则合并服务器i
和j
。 - 最后,通过查找每个服务器的根节点,并使用集合统计独立的根节点数量。
-
main
函数:- 从标准输入读取矩阵数据。
- 验证输入矩阵是否为 N×N 格式。
- 调用
count_broadcasts_union_find
函数并输出结果。
示例运行
示例 1:
输入:
1 0 0
0 1 0
0 0 1输出:
3
示例 2:
输入:
1 1
1 1输出:
1
使用方法
将上述代码保存为一个 Python 脚本,例如 broadcast_union_find.py
,然后在命令行中运行:
python broadcast_union_find.py
然后输入矩阵数据,按 Ctrl+D
(或在 Windows 上按 Ctrl+Z
然后回车)结束输入,程序将输出所需的广播次数。
时间复杂度和空间复杂度分析
时间复杂度
- 初始化并查集:
O(N)
- 遍历矩阵并执行合并操作:
- 对于一个 N×N 的矩阵,需要检查
N(N-1)/2
个元素(上三角部分)。 - 每次
find
和union
操作的时间复杂度接近于O(1)
,由于路径压缩和按秩合并的优化,整体近似为O(N²)
。
- 对于一个 N×N 的矩阵,需要检查
- 统计独立的根节点:
O(N)
,需要对每个节点执行find
操作。
总体时间复杂度: O(N²)
空间复杂度
- 存储并查集的父节点和秩数组:
O(N)
- 存储输入矩阵:
O(N²)
总体空间复杂度: O(N²)
比较并查集与 DFS 的方法
- 时间复杂度: 两者均为
O(N²)
,因为都需要遍历整个矩阵。 - 空间复杂度: 并查集额外使用
O(N)
的空间,而 DFS 使用O(N)
的辅助空间(访问数组和递归栈)。由于矩阵本身需要O(N²)
的空间存储,因此总体空间复杂度相同。
总结: 使用并查集和使用 DFS 在时间和空间复杂度上相似,选择哪种方法主要取决于个人偏好和具体应用场景。在某些情况下,并查集可能更易于实现和理解,尤其是在需要频繁合并和查询集合的情况下。
相关文章:
经典编程题:服务器广播
题目描述: 服务器连接方式包括直接相连,间接连接。A 和 B 直接连接,B 和 C 直接连接,则 A 和 C 间接连接。直接连接和间接连接都可以发送广播。 给出一个 N*N 数组,代表 N 个服务器,matrix[i][j]1…...

【网络协议】静态路由详解
网络中的路由器通过以下两种方式之一发现远程网络: 静态配置路由动态路由协议 在本文,我们将学习关于静态路由的各种概念,例如如何配置静态路由、路由表如何进行决策、路由接口等相关知识。 文章目录 引言直连网络静态路由路由表原则原则1原…...

朝天椒USB服务器在银泰证券虚拟化超融合场景的应用案例
在数字化浪潮席卷金融行业的今天,银泰证券作为业内知名的金融机构,始终致力于提升业务运营效率与数据安全性。面对虚拟化超融合场景下各种认证U盾的管理挑战,银泰证券选择了朝天椒USB服务器作为其解决方案,成功实现了U盾在虚拟机中…...

.NET framework、Core和Standard都是什么?
对于这些概念一直没有深入去理解,以至于经过.net这几年的发展进化,概念越来越多,越来越梳理不容易理解了。内心深处存在思想上的懒惰,以为自己专注于Unity开发就好,这些并不属于核心范畴,所以对这些概念总是…...

FairGuard游戏安全2024年度报告
导 读:2024年,国内游戏市场实际销售收入3257.83亿元,同比增长7.53%,游戏用户规模6.74亿人,同比增长0.94%,市场收入与用户规模双双实现突破,迎来了历史新高点。但游戏黑灰产规模也在迅速扩大&…...
JetBrains IDEs和Visual Studio Code的对比
JetBrains IDEs和Visual Studio Code的对比 JetBrains IDEs是捷克JetBrains公司开发的一系列集成开发环境(IDE)。以下是具体介绍:IntelliJ IDEA是JetBrains 公司的一款产品 主要产品 IntelliJ IDEA:一款功能强大且广泛应用的Java集成开发环境,有开源免费的社区版和商业收…...

文件剪切走:深度解析与高效恢复策略
一、文件剪切走现象解读 在计算机的日常使用中,“文件剪切走”这一术语形象地描述了文件在移动过程中意外丢失的现象。当用户尝试将文件从一个位置“剪切”并粘贴到另一个位置时,如果操作不当或系统出现异常,可能会导致文件在源位置消失&…...

Win32汇编学习笔记09.SEH和反调试
Win32汇编学习笔记09.SEH和反调试-C/C基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net SEH - structed exception handler 结构化异常处理 跟筛选一样都是用来处理异常的,但不同的是 筛选器是整个进程最终处理异常的函数,但无法做到比较精细的去处理异常(例如处理…...
[人工智能]CSDN创作助手体验
一、什么是智能体 智能体是一种能够感知环境、学习、推理和行动的实体。它可以是一个计算机程序、机器人或其他类似的系统。智能体的目标是通过与环境的交互来实现特定的任务或目标。 智能体通常由以下几个组件组成: 感知器:感知器是智能体与环境之间的…...

vue3中el-table实现多表头并表格合并行或列
1、el-table中添加事件 :span-method"genderSpanCity" <el-table :span-method"genderSpanCity":data"data.tableData":fit"true" table-layout"fixed" header-align"center" stripestyle"width:100%;he…...

HTML+CSS+JS制作中国传统节日主题网站(内附源码,含5个页面)
一、作品介绍 HTMLCSSJS制作一个中国传统节日主题网站,包含首页、节日介绍页、民俗文化页、节日活动页、联系我们页等5个静态页面。其中每个页面都包含一个导航栏、一个主要区域和一个底部区域。 二、页面结构 1. 顶部横幅区 包含传统中国风格的网站标题中国传统…...

时空笔记:CBEngine(微观交通模拟引擎)
CBEngine 是一个微观交通模拟引擎,可以支持城市规模的道路网络交通模拟。CBEngine 能够快速模拟拥有数千个交叉路口和数十万辆车辆的道路网络交通。 以下内容基本翻译自CBEngine — CBLab 1.0.0 documentation 1 模拟演示 1.0 模拟演示结构 config.cfg 定义了 roa…...

【LeetCode】力扣刷题热题100道(26-30题)附源码 轮转数组 乘积 矩阵 螺旋矩阵 旋转图像(C++)
目录 1.轮转数组 2.除自身以外数组的乘积 3.矩阵置零 4.螺旋矩阵 5.旋转图像 1.轮转数组 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 class Solution { public:void rotate(vector<int>& nums, int k) …...

【C++】字符串的 += 和 + 运算详解
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯1. 字符串的 和 基本用法1.1 的用法1.2 的用法 💯2. 示例代码的剖析与解释代码分析 💯3. 底层实现与性能分析3.1 的实现原理3.2 的实现原理3.…...

多模态大模型部署:结合dify
文章目录 前言minicpm-vDify测试一下总结部署过程回顾集成与测试实验结果分析展望未来 前言 上回说道,我们用ollama部署了一个多模态的大模型,也就是minicpm-v: 但这玩意儿感觉只能打字啊。 怎么给它发图片呢? minicpm-v Mini…...
Matlab Steger提取条纹中心(非极大值抑制)
文章目录 一、简介二、实现代码三、实现效果一、简介 由于在确定条纹的ROI区域之后,会计算出多个条纹中心坐标,因此这里就需要对其进行则优选择,毕竟条纹只有一条,这最简单的方式就是使用非极大值抑制,即选择每一行/列最好的条纹中心。 二、实现代码 Hessian2D.m function…...

springboot + vue+elementUI图片上传流程
1.实现背景 前端上传一张图片,存到后端数据库,并将图片回显到页面上。上传组件使用现成的elementUI的el-upload。、 2.前端页面 <el-uploadclass"upload-demo"action"http://xxxx.xxx.xxx:9090/file/upload" :show-file-list&q…...

LabVIEW 系统诊断
LabVIEW 系统诊断是指通过各种工具和方法检测、评估、分析和解决 LabVIEW 程序和硬件系统中可能存在的故障和性能问题。系统诊断不仅涵盖软件层面的调试与优化,还包括硬件交互、数据传输、实时性能等方面的检查和分析。一个成功的系统诊断能够显著提升LabVIEW应用程…...

韩国机场WebGIS可视化集合Google遥感影像分析
目录 前言 一、相关基础数据介绍 1、韩国的机场信息 2、空间数据准备 二、Leaflet叠加Google地图 1、叠加google地图 2、空间点的标记及展示 3、韩国机场空间分布 三、相关成果展示 1、务安国际机场 2、有同类问题的机场 四、总结 前言 12月29日8时57分左右务安国际机…...

springCloudGateWay使用总结
1、什么是网关 功能: ①身份认证、权限验证 ②服务器路由、负载均衡 ③请求限流 2、gateway搭建 2.1、创建一个空项目 2.2、引入依赖 2.3、加配置 3、断言工厂 4、过滤工厂 5、全局过滤器 6、跨域问题...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...