Problem

There is a network of n servers, labeled from 0 to n - 1. You are given a 2D integer array edges, where edges[i] = [ui, vi] indicates there is a message channel between servers ui and vi, and they can pass any number of messages to each other directly in one second. You are also given a 0-indexed integer array patience of length n.

All servers are connected, i.e., a message can be passed from one server to any other server(s) directly or indirectly through the message channels.

The server labeled 0 is the master server. The rest are data servers. Each data server needs to send its message to the master server for processing and wait for a reply. Messages move between servers optimally, so every message takes the least amount of time to arrive at the master server. The master server will process all newly arrived messages instantly and send a reply to the originating server via the reversed path the message had gone through.

At the beginning of second 0, each data server sends its message to be processed. Starting from second 1, at the beginning of every second, each data server will check if it has received a reply to the message it sent (including any newly arrived replies) from the master server:

  • If it has not, it will resend the message periodically. The data server i will resend the message every patience[i] second(s), i.e., the data server i will resend the message if patience[i] second(s) have elapsed since the last time the message was sent from this server.
  • Otherwise, no more resending will occur from this server.

The network becomes idle when there are no messages passing between servers or arriving at servers.

Return the earliest second starting from which the network becomes idle.

Examples

Example 1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Input:
edges = [[0,1],[1,2]], patience = [0,2,1]
Output:
 8
Explanation:
At (the beginning of) second 0,
- Data server 1 sends its message (denoted 1A) to the master server.
- Data server 2 sends its message (denoted 2A) to the master server.

At second 1,
- Message 1A arrives at the master server. Master server processes message 1A instantly and sends a reply 1A back.
- Server 1 has not received any reply. 1 second (1 < patience[1] = 2) elapsed since this server has sent the message, therefore it does not resend the message.
- Server 2 has not received any reply. 1 second (1 == patience[2] = 1) elapsed since this server has sent the message, therefore it resends the message (denoted 2B).

At second 2,
- The reply 1A arrives at server 1. No more resending will occur from server 1.
- Message 2A arrives at the master server. Master server processes message 2A instantly and sends a reply 2A back.
- Server 2 resends the message (denoted 2C).
...
At second 4,
- The reply 2A arrives at server 2. No more resending will occur from server 2.
...
At second 7, reply 2D arrives at server 2.

Starting from the beginning of the second 8, there are no messages passing between servers or arriving at servers.
This is the time when the network becomes idle.

Example 2:

graph TD
	0 --- 1
	1 --- 2
	2 --- 0
  
1
2
3
4
5
6
Input:
edges = [[0,1],[0,2],[1,2]], patience = [0,10,10]
Output:
 3
Explanation: Data servers 1 and 2 receive a reply back at the beginning of second 2.
From the beginning of the second 3, the network becomes idle.

Solution

Method 1 – BFS for Shortest Path and Message Timing

Intuition

The problem is about finding the time when all servers stop sending messages. Each server sends messages to the master server (node 0) and resends if no reply is received within its patience interval. The key is to find the shortest path from each server to the master and calculate when the last reply arrives, considering the patience value.

Approach

  1. Build the graph from the edges.
  2. Use BFS from node 0 to find the shortest path (distance) to each server.
  3. For each server i (except 0):
    • Calculate round-trip time: 2 * dist[i].
    • If patience[i] >= round-trip, only one message is sent.
    • Otherwise, the last message is sent at time ((round-trip-1)//patience[i])*patience[i].
    • The last reply arrives at last_sent_time + round-trip.
  4. The answer is the maximum last reply time among all servers, plus 1 (network becomes idle at the start of the next second).

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public:
    int networkBecomesIdle(vector<vector<int>>& edges, vector<int>& patience) {
        int n = patience.size();
        vector<vector<int>> g(n);
        for (auto& e : edges) {
            g[e[0]].push_back(e[1]);
            g[e[1]].push_back(e[0]);
        }
        vector<int> dist(n, -1);
        queue<int> q;
        q.push(0);
        dist[0] = 0;
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int v : g[u]) {
                if (dist[v] == -1) {
                    dist[v] = dist[u] + 1;
                    q.push(v);
                }
            }
        }
        int ans = 0;
        for (int i = 1; i < n; ++i) {
            int rtt = 2 * dist[i];
            int last = patience[i] >= rtt ? 0 : ((rtt - 1) / patience[i]) * patience[i];
            ans = max(ans, last + rtt);
        }
        return ans + 1;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
func networkBecomesIdle(edges [][]int, patience []int) int {
    n := len(patience)
    g := make([][]int, n)
    for _, e := range edges {
        g[e[0]] = append(g[e[0]], e[1])
        g[e[1]] = append(g[e[1]], e[0])
    }
    dist := make([]int, n)
    for i := range dist { dist[i] = -1 }
    q := []int{0}
    dist[0] = 0
    for len(q) > 0 {
        u := q[0]; q = q[1:]
        for _, v := range g[u] {
            if dist[v] == -1 {
                dist[v] = dist[u] + 1
                q = append(q, v)
            }
        }
    }
    ans := 0
    for i := 1; i < n; i++ {
        rtt := 2 * dist[i]
        last := 0
        if patience[i] < rtt {
            last = ((rtt-1)/patience[i])*patience[i]
        }
        if last+rtt > ans {
            ans = last + rtt
        }
    }
    return ans + 1
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution {
    public int networkBecomesIdle(int[][] edges, int[] patience) {
        int n = patience.length;
        List<Integer>[] g = new List[n];
        for (int i = 0; i < n; i++) g[i] = new ArrayList<>();
        for (int[] e : edges) {
            g[e[0]].add(e[1]);
            g[e[1]].add(e[0]);
        }
        int[] dist = new int[n];
        Arrays.fill(dist, -1);
        Queue<Integer> q = new LinkedList<>();
        q.offer(0);
        dist[0] = 0;
        while (!q.isEmpty()) {
            int u = q.poll();
            for (int v : g[u]) {
                if (dist[v] == -1) {
                    dist[v] = dist[u] + 1;
                    q.offer(v);
                }
            }
        }
        int ans = 0;
        for (int i = 1; i < n; i++) {
            int rtt = 2 * dist[i];
            int last = patience[i] >= rtt ? 0 : ((rtt - 1) / patience[i]) * patience[i];
            ans = Math.max(ans, last + rtt);
        }
        return ans + 1;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
    fun networkBecomesIdle(edges: Array<IntArray>, patience: IntArray): Int {
        val n = patience.size
        val g = Array(n) { mutableListOf<Int>() }
        for (e in edges) {
            g[e[0]].add(e[1])
            g[e[1]].add(e[0])
        }
        val dist = IntArray(n) { -1 }
        val q = ArrayDeque<Int>()
        q.add(0)
        dist[0] = 0
        while (q.isNotEmpty()) {
            val u = q.removeFirst()
            for (v in g[u]) {
                if (dist[v] == -1) {
                    dist[v] = dist[u] + 1
                    q.add(v)
                }
            }
        }
        var ans = 0
        for (i in 1 until n) {
            val rtt = 2 * dist[i]
            val last = if (patience[i] >= rtt) 0 else ((rtt - 1) / patience[i]) * patience[i]
            ans = maxOf(ans, last + rtt)
        }
        return ans + 1
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution:
    def networkBecomesIdle(self, edges: list[list[int]], patience: list[int]) -> int:
        from collections import deque, defaultdict
        n = len(patience)
        g = defaultdict(list)
        for u, v in edges:
            g[u].append(v)
            g[v].append(u)
        dist = [-1] * n
        q = deque([0])
        dist[0] = 0
        while q:
            u = q.popleft()
            for v in g[u]:
                if dist[v] == -1:
                    dist[v] = dist[u] + 1
                    q.append(v)
        ans = 0
        for i in range(1, n):
            rtt = 2 * dist[i]
            last = 0 if patience[i] >= rtt else ((rtt - 1) // patience[i]) * patience[i]
            ans = max(ans, last + rtt)
        return ans + 1
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use std::collections::{VecDeque, HashMap};
impl Solution {
    pub fn network_becomes_idle(edges: Vec<Vec<i32>>, patience: Vec<i32>) -> i32 {
        let n = patience.len();
        let mut g = vec![vec![]; n];
        for e in edges.iter() {
            g[e[0] as usize].push(e[1] as usize);
            g[e[1] as usize].push(e[0] as usize);
        }
        let mut dist = vec![-1; n];
        let mut q = VecDeque::new();
        q.push_back(0);
        dist[0] = 0;
        while let Some(u) = q.pop_front() {
            for &v in &g[u] {
                if dist[v] == -1 {
                    dist[v] = dist[u] + 1;
                    q.push_back(v);
                }
            }
        }
        let mut ans = 0;
        for i in 1..n {
            let rtt = 2 * dist[i];
            let last = if patience[i] >= rtt { 0 } else { ((rtt - 1) / patience[i]) * patience[i] };
            ans = ans.max(last + rtt);
        }
        ans + 1
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
    networkBecomesIdle(edges: number[][], patience: number[]): number {
        const n = patience.length;
        const g: number[][] = Array.from({length: n}, () => []);
        for (const [u, v] of edges) {
            g[u].push(v);
            g[v].push(u);
        }
        const dist = Array(n).fill(-1);
        const q: number[] = [0];
        dist[0] = 0;
        while (q.length) {
            const u = q.shift()!;
            for (const v of g[u]) {
                if (dist[v] === -1) {
                    dist[v] = dist[u] + 1;
                    q.push(v);
                }
            }
        }
        let ans = 0;
        for (let i = 1; i < n; i++) {
            const rtt = 2 * dist[i];
            const last = patience[i] >= rtt ? 0 : Math.floor((rtt - 1) / patience[i]) * patience[i];
            ans = Math.max(ans, last + rtt);
        }
        return ans + 1;
    }
}

Complexity

  • ⏰ Time complexity: O(n + m), where n is the number of servers and m is the number of edges.
  • 🧺 Space complexity: O(n + m), for the graph and BFS queue.