LeetCode 2039. 网络空闲的时刻
2039. 网络空闲的时刻
Solution
思路:一开始以为多源最短路径,但是n
太大了,突然看到边权都是1,所以可以直接BFS
,然后再根据每个点到源点的距离以及重发时间求最大即可。可以考虑三种情况:
-
\(patience\ge2*distance\):应为\(2*distance + 1\)
-
\(patience<2*distance\):至少为\(2*distance\),然后看收到回应后,最后一次在哪里。可以取余
-
\(2 * distance\ \% \ patience == 0\):说明是已经走了一个\(patiece\)的距离了,
应为:\(2*distance+2*distance-patience\)
-
\(2*distance\ \% \ patience != 0\):说明已经走了\((2*distance\ \% \ patience)\),
应为:\(2*distance+2*distance-(2*distance\ \% \ patience)\)
-
题解中没有记录距离,每次处理一层,直接取出当前队列里的所有节点,计算结果后,距离加一继续搜其他点。
//版本一
class Solution {
public int networkBecomesIdle(int[][] edges, int[] patience) {
int n = patience.length;
Map<Integer, List<Integer>> map = new HashMap<>();
Set<Integer> vis = new HashSet<>();
Map<Integer, Integer> dis = new HashMap<>();
for (int[] edge : edges) {
int u = edge[0], v = edge[1];
if (!map.containsKey(u)) {
map.put(u, new ArrayList<>());
}
if (!map.containsKey(v)) {
map.put(v, new ArrayList<>());
}
map.get(u).add(v);
map.get(v).add(u);
}
Deque<int[]> deque = new ArrayDeque<>();
deque.push(new int[]{0, 0});
vis.add(0);
dis.put(0, 0);
while (!deque.isEmpty()) {
int[] cur = deque.remove();
int u = cur[0], step = cur[1];
for (int v : map.get(u)) {
if (vis.add(v)) {
deque.add(new int[]{v, step + 1});
dis.put(v, step + 1);
}
}
}
int ans = Integer.MIN_VALUE;
for (int i = 1; i < n; i++) {
int distance = dis.get(i);
if (patience[i] >= 2 * distance) {
ans = Math.max(ans, 2 * distance);
} else {
ans = Math.max(ans, 2 * distance % patience[i] == 0 ?
4 * distance - patience[i] : 4 * distance - (2 * distance % patience[i]));
}
}
return ans + 1;
}
}
发现Set
和Map
没有必要,统一用整数的dis
数组即可。
//版本二
class Solution {
public int networkBecomesIdle(int[][] edges, int[] patience) {
int n = patience.length;
Map<Integer, List<Integer>> map = new HashMap<>();
// Set<Integer> vis = new HashSet<>();
int[] dis = new int[n];
// Map<Integer, Integer> dis = new HashMap<>();
for (int[] edge : edges) {
int u = edge[0], v = edge[1];
if (!map.containsKey(u)) {
map.put(u, new ArrayList<>());
}
if (!map.containsKey(v)) {
map.put(v, new ArrayList<>());
}
map.get(u).add(v);
map.get(v).add(u);
}
Deque<int[]> deque = new ArrayDeque<>();
deque.push(new int[]{0, 0});
while (!deque.isEmpty()) {
int[] cur = deque.remove();
int u = cur[0], step = cur[1];
for (int v : map.get(u)) {
if (dis[v] == 0) {
deque.add(new int[]{v, step + 1});
dis[v] = step + 1;
}
}
}
int ans = Integer.MIN_VALUE;
for (int i = 1; i < n; i++) {
int distance = dis[i];
if (patience[i] >= 2 * distance) {
ans = Math.max(ans, 2 * distance);
} else {
ans = Math.max(ans, 2 * distance % patience[i] == 0 ?
4 * distance - patience[i] : 4 * distance - (2 * distance % patience[i]));
}
}
return ans + 1;
}
}
进一步,不想用Map
来构建图,所以换成了前向星。这里使用了class
类的写法,开成数组也可以。学习一下static
优化的数组写法。
class Solution {
int cnt = 0;
int[] head;
Edge[] edgeArray;
public int networkBecomesIdle(int[][] edges, int[] patience) {
int n = patience.length;
head = new int[n];
Arrays.fill(head, -1);
int[] dis = new int[n];
edgeArray = new Edge[edges.length * 2];
for (int[] edge : edges) {
add(edge[0], edge[1]);
add(edge[1], edge[0]);
}
Deque<int[]> deque = new ArrayDeque<>();
deque.push(new int[]{0, 0});
while (!deque.isEmpty()) {
int[] cur = deque.remove();
int u = cur[0], step = cur[1];
for (int i = head[u]; i != -1; i = edgeArray[i].nxt) {
int v = edgeArray[i].to;
if (dis[v] == 0) {
deque.add(new int[]{v, step + 1});
dis[v] = step + 1;
}
}
}
int ans = Integer.MIN_VALUE;
for (int i = 1; i < n; i++) {
int distance = dis[i];
if (patience[i] >= 2 * distance) {
ans = Math.max(ans, 2 * distance);
} else {
ans = Math.max(ans, 2 * distance % patience[i] == 0 ?
4 * distance - patience[i] : 4 * distance - (2 * distance % patience[i]));
}
}
return ans + 1;
}
void add(int u, int v) {
Edge edge = new Edge();
edge.dis = 1;
edge.to = v;
edge.nxt = head[u];
edgeArray[cnt] = edge;
head[u] = cnt++;
}
}
class Edge {
int to;
int nxt;
int dis;
}
static int N = 100010, M = N * 2, INF = 0x3f3f3f3f;
static int[] he = new int[N], e = new int[M], ne = new int[M];
static int[] dist = new int[N];
int idx;
void add(int a, int b) {
e[idx] = b;
ne[idx] = he[a];
he[a] = idx++;
}
Arrays.fill(he, -1);
Arrays.fill(dist, INF);
for (int i = he[t]; i != -1; i = ne[i]) {
int j = e[i];
}
埋骨何须桑梓地,人生无处不青山