题目描述
某地有N个广播站,站点之间有些有连接,有些没有。有连接的站点在接受到广播后会互相发送。
给定一个N*N的二维数组matrix,数组的元素都是字符’0’或者’1’。
matrix[i][j] = ‘1’, 代表i和j站点之间有连接,
matrix[i][j] = ‘0’, 代表没连接,
现在要发一条广播,问初始最少给几个广播站发送,才能保证所有的广播站都收到消息。
输入描述
从stdin输入,共一行数据,表示二维数组的各行,用逗号分隔行。保证每行字符串所含的字符数一样的。
比如:110,110,001。
输出描述
返回初始最少需要发送广播站个数
用例
输入
110,110,001
输出
2
说明
站点1和站点2直接有连接,站点3和其他的都没连接,所以开始至少需要给两个站点发送广播。
输入
100,010,001
输出
3
说明
3台服务器互不连接,所以需要分别广播这3台服务器。
输入
11,11
思路
问题本质转化
- 每个广播站是一个 节点(编号 0 到 N-1,N 是广播站数量);
matrix[i][j] = '1'表示节点 i 和 j 之间有 无向边(双向连通);- “初始最少发送广播的个数” = 无向图中 连通分量的数量(每个连通分量只需给一个节点发广播,整个分量都会通过连接传播到所有节点)。
两种核心解法(并查集 / DFS)
解法一:并查集(推荐,效率高、代码简洁)
并查集的核心作用是 动态维护节点的连通关系,并快速查询连通分量数量。
并查集解题步骤
- 初始化:
- 每个节点的父节点初始化为自身(
parent[i] = i); - 用
count记录连通分量初始数量(等于节点总数 N)。
- 每个节点的父节点初始化为自身(
- 遍历所有边:
- 遍历二维数组
matrix,对于每个i < j(避免重复处理无向边,因为matrix[i][j]和matrix[j][i]是同一连接):- 若
matrix[i][j] == '1',说明 i 和 j 连通,执行 合并操作; - 合并前先查询 i 和 j 的根节点:若根节点不同,说明两个连通分量可以合并,
count--(连通分量数量减少 1)。
- 若
- 遍历二维数组
- 返回结果:最终
count就是最少需要发送广播的个数。
并查集代码实现
function solution() {
const rows = readline().split(',');
const n = rows.length; // 广播站数量
// 并查集初始化:parent[i] = i
const parent = new Array(n);
for (let i = 0; i < n; i++) {
parent[i] = i;
}
// 查找根节点(带路径压缩)
const find = (x) => {
if (parent[x] !== x) {
parent[x] = find(parent[x]); // 路径压缩,加速后续查询
}
return parent[x];
};
// 合并两个集合(按秩合并)
const

最低0.47元/天 解锁文章
3441

被折叠的 条评论
为什么被折叠?



