这道题要求在规定时间内从城市0到城市n-1,途中可以停留,求最小花费(通行费总和)。这是一个带时间约束的最短路问题,适合用动态规划解决。

解题思路

定义 dp[t][i] 表示在时间 t 到达城市 i 的最小花费。

状态转移:
对于每条边 (u, v, time),可以从 u 走到 v(或反向):

```
dp[t + time][v] = min(dp[t + time][v], dp[t][u] + toll[v])
```

初始化:

· dp[0][0] = toll[0](从城市0出发,需要支付城市0的通行费)
· 其余 dp[t][i] = INF

答案:
在 t ∈ [0, maxTime] 范围内,取 dp[t][n-1] 的最小值。如果所有值都是 INF,返回 -1。

Go 实现

```go
func minCost(maxTime int, edges [][]int, toll []int) int {
    n := len(toll)
    const INF = 1 << 30
    
    // dp[t][i] 表示在时间t到达城市i的最小花费
    dp := make([][]int, maxTime+1)
    for t := 0; t <= maxTime; t++ {
        dp[t] = make([]int, n)
        for i := 0; i < n; i++ {
            dp[t][i] = INF
        }
    }
    
    // 初始状态:时间0在城市0,花费为toll[0]
    dp[0][0] = toll[0]
    
    // 按时间递增顺序进行状态转移
    for t := 0; t <= maxTime; t++ {
        for _, edge := range edges {
            u, v, time := edge[0], edge[1], edge[2]
            // 从 u -> v
            if t+time <= maxTime && dp[t][u] != INF {
                if dp[t][u] + toll[v] < dp[t+time][v] {
                    dp[t+time][v] = dp[t][u] + toll[v]
                }
            }
            // 从 v -> u
            if t+time <= maxTime && dp[t][v] != INF {
                if dp[t][v] + toll[u] < dp[t+time][u] {
                    dp[t+time][u] = dp[t][v] + toll[u]
                }
            }
        }
    }
    
    // 找最小花费
    ans := INF
    for t := 0; t <= maxTime; t++ {
        if dp[t][n-1] < ans {
            ans = dp[t][n-1]
        }
    }
    
    if ans == INF {
        return -1
    }
    return ans
}
```

复杂度分析

· 时间复杂度:O(maxTime * E),其中 E 是边的数量。
· 空间复杂度:O(maxTime * n)。

关键点说明

1. 逐时间递推:因为每条边走完需要整数时间,并且可以重复访问城市(在某个城市等待),所以按时间维度从小到大更新是安全的。
2. 双向边处理:无向图,每条边两个方向都要考虑。
3. 初始化:dp[0][0] = toll[0] 表示起点也要付费,其余设为极大值。
4. 最终答案:到达终点的时间可以是 [0, maxTime] 内的任意整数,取最小花费。

 

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐