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;
    }
}

发现SetMap没有必要,统一用整数的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];
}
posted @ 2022-03-20 16:15  Frontierone  阅读(34)  评论(0编辑  收藏  举报