华为OD机试真题 - 最长广播响应 (C++ & Python & JAVA & JS & GO)

最长广播响应

2025华为OD机试 - 华为OD上机考试 200分题型

华为OD机试真题目录点击查看: 华为OD机试真题题库目录|机考题库 + 算法考点详解

题目描述

某通信网络中有N个网络结点,用1到N进行标识。

网络中的结点互联互通,且结点之间的消息传递有时延,相连结点的时延均为一个时间单位。

现给定网络结点的连接关系link[i]={u,v},其中u和v表示网络结点。

当指定一个结点向其他结点进行广播,所有被广播结点收到消息后都会在原路径上回复一条响应消息,请计算发送结点至少需要等待几个时间单位才能收到所有被广播结点的响应消息。

备注:

  1. N的取值范围为[1,100];
  2. 连接关系link的长度不超过3000,且1 <= u,v <= N;
  3. 网络中任意结点间均是可达的;

输入描述

输入的第一行为两个正整数,分别表示网络结点的个数N,以及时延列表的长度T;

接下来的T行输入,表示结点间的连接关系列表;

最后一行的输入为一个正整数,表示指定的广播结点序号;

输出描述

输出一个整数,表示发送结点接收到所有响应消息至少需要等待的时长。

用例1

输入

none 复制代码
5 7
1 4
2 1
2 3
2 4
3 4
3 5
4 5
2

输出

none 复制代码
4

说明

结点2到5的最小时延为2,到剩余结点的最小时延均为1,所以至少要等待2*2=4s。

题解

思路: 最短路算法

  1. 输出最少需要多少时间才能接受到全部节点的响应这句话可以理解为从点u到达所有点的最短距离的最大值 * 2
  2. 这道题就可以转换成求点单点最短路。可以是使用经典的dijkstra(迪杰斯特拉)来解决。可以去详细学学这个算法,简单说一些迪杰斯特拉算法的思路:
  • 算法的本质是贪心算法,使用当前找到的最短距离去更新与之相邻的点的距离.
  • 假设当前点u距离为最小值,更新与之相邻的点离启动的距离,状态转移方程为 当(dist[u] + w < dist[v])时, dist[v] = dis[u] + w。
  1. 遍历起点到所有点的距离找出其中最大值 * 2就是结果。

c++

c++ 复制代码
#include <functional>
#include<iostream>
#include<vector>
#include<string>
#include <utility> 
#include <sstream>
#include<algorithm>
#include <limits>
#include<queue>
using namespace std;
const int INF = numeric_limits<int>::max();


// 迪杰斯特拉求最短路径
int dijkstra(int start, const vector<vector<int>>& graph) {
    int n = graph.size();
    vector<int> dist(n, INF);
    dist[start] = 0;
    // 优先队列(最小堆,小的优先级高)
    priority_queue<pair<int,int>, vector<pair<int, int>>, greater<>> pq;
    pq.push({0, start});
    while (!pq.empty()) { 
        auto [d,u] = pq.top();
        pq.pop();
   
        if (d > dist[u]) {
            continue;
        }
        // 更新与点u相连的点 
        for (const auto& v : graph[u]) {
            if (dist[u] + 1 < dist[v]) {
                dist[v] = dist[u] + 1;
                pq.push({dist[v], v});
            }
        }
    }
    
    // 单向最长时延
    int res = 0;
    for (int i =0; i < n; i++) {
        if (dist[i] == INF) {
            res = -1;
            break;
        }
        res = max(res, dist[i]);
    }
    return res;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> g(n);
    while (m--) {
        int x, y;
        cin >> x >> y;
        g[x-1].push_back(y-1);
        g[y-1].push_back(x-1);
    }
    int pos;
    cin >> pos;
    int res = dijkstra(pos-1, g);
    // 往返 * 2
    cout << res * 2;
    return 0;
}

JAVA

JAVA 复制代码
import java.io.*;
import java.util.*;

/**
 * 迪杰斯特拉算法求最短路径
 */
public class Main {

    static final int INF = Integer.MAX_VALUE;

    static int dijkstra(int start, List<List<Integer>> graph) {
        int n = graph.size();
        int[] dist = new int[n];
        Arrays.fill(dist, INF);
        dist[start] = 0;

        // 优先队列(最小堆,距离小的优先)
        PriorityQueue<int[]> pq = new PriorityQueue<>(
                (a, b) -> Integer.compare(a[0], b[0])
        );
        pq.offer(new int[]{0, start});

        while (!pq.isEmpty()) {
            int[] cur = pq.poll();
            int d = cur[0], u = cur[1];

            if (d > dist[u]) continue;

            // 更新与 u 相连的点
            for (int v : graph.get(u)) {
                if (dist[u] + 1 < dist[v]) {
                    dist[v] = dist[u] + 1;
                    pq.offer(new int[]{dist[v], v});
                }
            }
        }

        // 单向最长时延
        int res = 0;
        for (int i = 0; i < n; i++) {
            if (dist[i] == INF) return -1;
            res = Math.max(res, dist[i]);
        }
        return res;
    }

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        int m = sc.nextInt();

        List<List<Integer>> g = new ArrayList<>();
        for (int i = 0; i < n; i++) g.add(new ArrayList<>());

        while (m-- > 0) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            g.get(x - 1).add(y - 1);
            g.get(y - 1).add(x - 1);
        }

        int pos = sc.nextInt();
        int res = dijkstra(pos - 1, g);

        // 往返 * 2
        System.out.println(res * 2);
    }
}

Python

python 复制代码
import sys
import heapq

INF = 10**18

# 迪杰斯特拉求最短路径
def dijkstra(start, graph):
    n = len(graph)
    dist = [INF] * n
    dist[start] = 0

    # 最小堆(距离小的优先)
    pq = [(0, start)]

    while pq:
        d, u = heapq.heappop(pq)
        if d > dist[u]:
            continue

        # 更新与 u 相连的点
        for v in graph[u]:
            if dist[u] + 1 < dist[v]:
                dist[v] = dist[u] + 1
                heapq.heappush(pq, (dist[v], v))

    # 单向最长时延
    res = 0
    for d in dist:
        if d == INF:
            return -1
        res = max(res, d)
    return res


def main():
    data = list(map(int, sys.stdin.read().split()))
    idx = 0

    n, m = data[idx], data[idx + 1]
    idx += 2

    g = [[] for _ in range(n)]
    for _ in range(m):
        x, y = data[idx], data[idx + 1]
        idx += 2
        g[x - 1].append(y - 1)
        g[y - 1].append(x - 1)

    pos = data[idx]
    res = dijkstra(pos - 1, g)

    # 往返 * 2
    print(res * 2)


if __name__ == "__main__":
    main()

JavaScript

js 复制代码
const readline = require('readline');

// 最小堆实现
class MinHeap {
    constructor() {
        this.heap = [];
    }

    push(item) {
        this.heap.push(item);
        this._up(this.heap.length - 1);
    }

    pop() {
        const top = this.heap[0];
        const last = this.heap.pop();
        if (this.heap.length > 0) {
            this.heap[0] = last;
            this._down(0);
        }
        return top;
    }

    isEmpty() {
        return this.heap.length === 0;
    }

    _up(i) {
        while (i > 0) {
            let p = (i - 1) >> 1;
            if (this.heap[p][0] <= this.heap[i][0]) break;
            [this.heap[p], this.heap[i]] = [this.heap[i], this.heap[p]];
            i = p;
        }
    }

    _down(i) {
        const n = this.heap.length;
        while (true) {
            let l = i * 2 + 1;
            let r = i * 2 + 2;
            let min = i;
            if (l < n && this.heap[l][0] < this.heap[min][0]) min = l;
            if (r < n && this.heap[r][0] < this.heap[min][0]) min = r;
            if (min === i) break;
            [this.heap[i], this.heap[min]] = [this.heap[min], this.heap[i]];
            i = min;
        }
    }
}

// 迪杰斯特拉求最短路径(无权图,边权=1)
function dijkstra(start, graph) {
    const n = graph.length;
    const INF = 1e18;
    const dist = Array(n).fill(INF);
    dist[start] = 0;

    // 优先队列(最小堆,距离小的优先)
    const pq = new MinHeap();
    pq.push([0, start]);

    while (!pq.isEmpty()) {
        const [d, u] = pq.pop();
        if (d > dist[u]) continue;

        // 更新与点 u 相连的点
        for (const v of graph[u]) {
            if (dist[u] + 1 < dist[v]) {
                dist[v] = dist[u] + 1;
                pq.push([dist[v], v]);
            }
        }
    }

    // 单向最长时延
    let res = 0;
    for (const d of dist) {
        if (d === INF) return -1;
        res = Math.max(res, d);
    }
    return res;
}
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const input = [];
rl.on('line', line => {
    input.push(line.trim());
});

rl.on('close', () => {
    // 按空白切分成数字
    const data = input.join(' ').split(/\s+/).map(Number);
    let idx = 0;

    const n = data[idx++];
    const m = data[idx++];

    const g = Array.from({ length: n }, () => []);

    for (let i = 0; i < m; i++) {
        const x = data[idx++];
        const y = data[idx++];
        g[x - 1].push(y - 1);
        g[y - 1].push(x - 1);
    }

    const pos = data[idx++];

    const res = dijkstra(pos - 1, g);

    // 往返 * 2
    console.log(res * 2);
});

Go

go 复制代码
package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
)

const INF = int(1e9)

// 优先队列节点
type Node struct {
	dist int
	u    int
}

// 最小堆
type PriorityQueue []Node

func (pq PriorityQueue) Len() int            { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool  { return pq[i].dist < pq[j].dist }
func (pq PriorityQueue) Swap(i, j int)       { pq[i], pq[j] = pq[j], pq[i] }
func (pq *PriorityQueue) Push(x interface{}) {
	*pq = append(*pq, x.(Node))
}
func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	x := old[n-1]
	*pq = old[:n-1]
	return x
}

// 迪杰斯特拉求最短路径
func dijkstra(start int, graph [][]int) int {
	n := len(graph)
	dist := make([]int, n)
	for i := 0; i < n; i++ {
		dist[i] = INF
	}
	dist[start] = 0

	pq := &PriorityQueue{}
	heap.Init(pq)
	heap.Push(pq, Node{0, start})

	for pq.Len() > 0 {
		cur := heap.Pop(pq).(Node)
		d, u := cur.dist, cur.u
		if d > dist[u] {
			continue
		}

		// 更新与 u 相连的点
		for _, v := range graph[u] {
			if dist[u]+1 < dist[v] {
				dist[v] = dist[u] + 1
				heap.Push(pq, Node{dist[v], v})
			}
		}
	}

	// 单向最长时延
	res := 0
	for i := 0; i < n; i++ {
		if dist[i] == INF {
			return -1
		}
		if dist[i] > res {
			res = dist[i]
		}
	}
	return res
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n, m int
	fmt.Fscan(in, &n, &m)

	g := make([][]int, n)
	for i := 0; i < m; i++ {
		var x, y int
		fmt.Fscan(in, &x, &y)
		g[x-1] = append(g[x-1], y-1)
		g[y-1] = append(g[y-1], x-1)
	}

	var pos int
	fmt.Fscan(in, &pos)

	res := dijkstra(pos-1, g)

	// 往返 * 2
	fmt.Println(res * 2)
}
相关推荐
我是华为OD~HR~栗栗呀1 天前
(华为od)Python面经-20届
华为od
兩尛6 天前
猴子爬山od
算法·华为od
我是华为OD~HR~栗栗呀7 天前
23届(华为od)-C开发面经
java·c语言·c++·python·华为od·华为·面试
兩尛7 天前
【华为OD机试】运维日志排序
java·数据结构·华为od
Tony_yitao10 天前
12.华为OD机试 - N个选手比赛前三名、比赛(Java 双机位A卷 100分)
java·算法·华为od·algorithm
我是华为OD~HR~栗栗呀11 天前
华为OD-C面经-23届学院哦
java·c++·python·华为od·华为·面试
无限码力14 天前
【全网首发】2025华为OD机试双机位C卷(机考全真题库)含考点说明(华为OD上机考试双机位C卷)
华为od·华为od机考·华为od机试·华为od机试双机位c卷·华为od机考双机位c卷·华为od上机考试双机位c卷
询问QQ:2769988519 天前
RRT星三维路径搜索Matlab代码分享[特殊字符]
华为od
uesowys22 天前
华为OD算法开发指导-任务规划
华为od·算法开发指导