题目链接
题意:
给定一张n个点不含重边的无向图,点的编号从0开始到n-1,两点之间如果有连边,可以认为耗时为1秒
1->n-1的点都需要向0号点发送消息(从第0秒开始)
在0号收到消息之后,会回复消息;
从第一秒开始,如果1->n-1号服务器经过patiennce[]时间都还没有收到回复的消息,那么就会重新发送请求的消息
问最早的网络中没有消息传输的时间是什么时候
思路:
最早的没有消息传输的时间为所有点空闲的时间中最晚的那个时间节点
bfs
设一个点u到0号点的距离为dis,并且经过t秒后会重新发送消息,那么说:
{
从发送到回复消息所需要消耗的时间为dis * 2
-
d
i
s
∗
2
≤
t
dis * 2 \leq t
dis∗2≤t,在这种情况下,还没有重新发送消息就已经得到了回复,这个点的空闲时间为dis*2+1
-
d
i
s
∗
2
>
t
dis * 2 > t
dis∗2>t,在这种情况下,没有收到消息并且再次发送请求,在dis2-1时间内,发送请求的次数为cnt = (dis2-1) / t,那么说我们可以得到最后一次发送消息的时候是
t
∗
c
n
t
t * cnt
t∗cnt,并且会在
l
a
s
t
R
e
p
l
y
=
t
∗
c
n
t
+
d
i
s
∗
2
lastReply = t*cnt + dis*2
lastReply=t∗cnt+dis∗2的时候收到最后一次的回复,那么这个点的空闲时间为
l
a
s
t
R
e
p
l
y
+
1
lastReply+1
lastReply+1
}
第一种情况中,
c
n
t
=
0
cnt = 0
cnt=0,所以说可以合并为同一个式子
Code:
class Solution {
public:
int networkBecomesIdle(vector<vector<int>>& edges, vector<int>& patience) {
int n = patience.size();
vector<vector<int>> edg(n);
vector<bool> vis(n,false);
queue<int> que;
for(vector<int> vt:edges) {
int u = vt[0],v = vt[1];
edg[u].push_back(v);
edg[v].push_back(u);
}
que.push(0);
vis[0] = 1;
int ans = 0, dist = 1;
int siz = que.size();
while(que.size()) {
int frt = que.front();
que.pop();
for(int u:edg[frt]) {
if(vis[u]) continue;
vis[u] = 1;
que.push(u);
int t = patience[u] * ((2 * dist - 1) / patience[u]) + 2 * dist + 1;
ans = max(ans, t);
}
if(siz) siz --;
if(siz == 0) {
dist ++;
siz = que.size();
}
}
return ans;
}
};