跳转至

3778. 排除一个最大权重边的最小距离 🔒

题目描述

给定一个正整数 n 和一个二维整数数组 edges,其中 edges[i] = [ui, vi, wi]

有一个 带权连通 简单无向图,包含 n 个节点,下标从 0n - 1。每条边 [ui, vi, wi] 表示在节点 ui 和节点 vi 之间有一条 权边 wi

路径的 开销 是路径中边的权重之 排除 权重 最大 的那条边。如果路径中有多个权重最大的边, 排除 第一个 这样的边。

返回一个整数表示从节点 0 到节点 n - 1 的 最小 开销。

 

示例 1:

输入:n = 5, edges = [[0,1,2],[1,2,7],[2,3,7],[3,4,4]]

输出:13

解释:

从节点 0 到节点 4 只有一条路径: 0 -> 1 -> 2 -> 3 -> 4.

路径上边的权重是 2,7,7 和 4。

排除第一条权重最大的边,即 1 -> 2,路径的开销是 2 + 7 + 4 = 13

示例 2:

输入:n = 3, edges = [[0,1,1],[1,2,1],[0,2,50000]]

输出:0

解释:

从节点 0 到 2 有两条路径:

  • 0 -> 1 -> 2

路径上边的权重是 1 和 1。

排除第一条权重最大的边,即 0 -> 1,路径的开销是 1

  • 0 -> 2

这条路径上唯一的边权重是1。

排除第一条权重最大的边,即 0 -> 2,路径的开销是 0

最小的开销是 min(1, 0) = 0

 

提示:

  • 2 <= n <= 5 * 104
  • n - 1 <= edges.length <= 109
  • edges[i] = [ui, vi, wi]
  • 0 <= ui < vi < n
  • [ui, vi] != [uj, vj]
  • 1 <= wi <= 5 * 104
  • 图是连通的。

解法

方法一

 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
class Solution:
    def minCostExcludingMax(self, n: int, edges: List[List[int]]) -> int:
        g = [[] for _ in range(n)]
        for u, v, w in edges:
            g[u].append((v, w))
            g[v].append((u, w))
        dist = [[inf] * 2 for _ in range(n)]
        dist[0][0] = 0
        pq = [(0, 0, 0)]
        while pq:
            cur, u, used = heappop(pq)
            if cur > dist[u][used]:
                continue
            if u == n - 1 and used:
                return cur
            for v, w in g[u]:
                nxt = cur + w
                if nxt < dist[v][used]:
                    dist[v][used] = nxt
                    heappush(pq, (nxt, v, used))
                if used == 0:
                    nxt = cur
                    if nxt < dist[v][1]:
                        dist[v][1] = nxt
                        heappush(pq, (nxt, v, 1))
        return dist[n - 1][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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Solution {
    public long minCostExcludingMax(int n, int[][] edges) {
        List<int[]>[] g = new ArrayList[n];
        Arrays.setAll(g, k -> new ArrayList<>());
        for (int[] e : edges) {
            int u = e[0], v = e[1], w = e[2];
            g[u].add(new int[]{v, w});
            g[v].add(new int[]{u, w});
        }

        long inf = Long.MAX_VALUE / 4;
        long[][] dist = new long[n][2];
        for (int i = 0; i < n; i++) {
            dist[i][0] = inf;
            dist[i][1] = inf;
        }
        dist[0][0] = 0;

        PriorityQueue<long[]> pq = new PriorityQueue<>(Comparator.comparingLong(a -> a[0]));
        pq.add(new long[]{0, 0, 0});

        while (!pq.isEmpty()) {
            long[] t = pq.poll();
            long cur = t[0];
            int u = (int) t[1];
            int used = (int) t[2];

            if (cur > dist[u][used]) {
                continue;
            }
            if (u == n - 1 && used == 1) {
                return cur;
            }

            for (int[] ed : g[u]) {
                int v = ed[0], w = ed[1];
                long nxt = cur + w;
                if (nxt < dist[v][used]) {
                    dist[v][used] = nxt;
                    pq.add(new long[]{nxt, v, used});
                }

                if (used == 0) {
                    nxt = cur;
                    if (nxt < dist[v][1]) {
                        dist[v][1] = nxt;
                        pq.add(new long[]{nxt, v, 1});
                    }
                }
            }
        }

        return dist[n - 1][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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Solution {
public:
    long long minCostExcludingMax(int n, vector<vector<int>>& edges) {
        vector<vector<pair<int, int>>> g(n);
        for (auto& e : edges) {
            int u = e[0], v = e[1], w = e[2];
            g[u].push_back({v, w});
            g[v].push_back({u, w});
        }

        long long inf = LLONG_MAX / 4;
        vector<array<long long, 2>> dist(n, {inf, inf});
        dist[0][0] = 0;

        priority_queue<array<long long, 3>, vector<array<long long, 3>>, greater<array<long long, 3>>> pq;
        pq.push({0, 0, 0});

        while (!pq.empty()) {
            auto t = pq.top();
            pq.pop();
            long long cur = t[0];
            int u = t[1];
            int used = t[2];

            if (cur > dist[u][used]) {
                continue;
            }
            if (u == n - 1 && used == 1) {
                return cur;
            }

            for (auto [v, w] : g[u]) {
                long long nxt = cur + w;
                if (nxt < dist[v][used]) {
                    dist[v][used] = nxt;
                    pq.push({nxt, v, used});
                }

                if (used == 0) {
                    nxt = cur;
                    if (nxt < dist[v][1]) {
                        dist[v][1] = nxt;
                        pq.push({nxt, v, 1});
                    }
                }
            }
        }

        return dist[n - 1][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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
func minCostExcludingMax(n int, edges [][]int) int64 {
    g := make([][]edge, n)
    for _, e := range edges {
        u, v, w := e[0], e[1], e[2]
        g[u] = append(g[u], edge{v, w})
        g[v] = append(g[v], edge{u, w})
    }

    inf := int64(math.MaxInt64 / 4)
    dist := make([][2]int64, n)
    for i := 0; i < n; i++ {
        dist[i][0] = inf
        dist[i][1] = inf
    }
    dist[0][0] = 0

    pq := hp{{0, 0, 0}}
    for len(pq) > 0 {
        t := heap.Pop(&pq).(state)
        cur, u, used := t.cur, t.u, t.used
        if cur > dist[u][used] {
            continue
        }
        if u == n-1 && used == 1 {
            return cur
        }
        for _, ed := range g[u] {
            v, w := ed.to, int64(ed.w)

            nxt := cur + w
            if nxt < dist[v][used] {
                dist[v][used] = nxt
                heap.Push(&pq, state{nxt, v, used})
            }

            if used == 0 {
                nxt = cur
                if nxt < dist[v][1] {
                    dist[v][1] = nxt
                    heap.Push(&pq, state{nxt, v, 1})
                }
            }
        }
    }
    return dist[n-1][1]
}

type edge struct {
    to int
    w  int
}

type state struct {
    cur  int64
    u    int
    used int
}

type hp []state

func (h hp) Len() int           { return len(h) }
func (h hp) Less(i, j int) bool { return h[i].cur < h[j].cur }
func (h hp) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(x any)        { *h = append(*h, x.(state)) }
func (h *hp) Pop() (x any)      { a := *h; x = a[len(a)-1]; *h = a[:len(a)-1]; return }
 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
34
35
36
37
38
39
40
41
42
43
44
function minCostExcludingMax(n: number, edges: number[][]): number {
    const g: [number, number][][] = Array.from({ length: n }, () => []);
    for (const [u, v, w] of edges) {
        g[u].push([v, w]);
        g[v].push([u, w]);
    }

    const INF = Infinity;
    const dist: number[][] = Array.from({ length: n }, () => [INF, INF]);
    dist[0][0] = 0;

    const pq = new PriorityQueue<[number, number, number]>((a, b) =>
        a[0] === b[0] ? a[1] - b[1] : a[0] - b[0],
    );

    pq.enqueue([0, 0, 0]);

    while (pq.size() > 0) {
        const [cur, u, used] = pq.dequeue()!;
        if (cur > dist[u][used]) {
            continue;
        }
        if (u === n - 1 && used === 1) {
            return cur;
        }

        for (const [v, w] of g[u]) {
            const nxt1 = cur + w;
            if (nxt1 < dist[v][used]) {
                dist[v][used] = nxt1;
                pq.enqueue([nxt1, v, used]);
            }
            if (used === 0) {
                const nxt2 = cur;
                if (nxt2 < dist[v][1]) {
                    dist[v][1] = nxt2;
                    pq.enqueue([nxt2, v, 1]);
                }
            }
        }
    }

    return dist[n - 1][1];
}

评论