解题思路

这是一个单源最短路径问题。关键点如下:

  1. 给定起点(0)和终点
  2. 每条公交线路有起点、终点和所需时间
  3. 需要计算从起点到终点的最少时间
  4. 可以多次换乘公交

解题思路:

  1. 使用Bellman-Ford算法求解单源最短路径
  2. 每条边代表一条公交线路
  3. 边的权重为乘坐该线路所需的时间
  4. 不断松弛所有边,直到无法更新为止

代码

#include <iostream>
#include <vector>
#include <unordered_map>
#include <climits>
using namespace std;

struct Edge {
    int from, to, weight;
    Edge(int f, int t, int w) : from(f), to(t), weight(w) {}
};

int main() {
    int end, n;
    cin >> end >> n;
    
    vector<Edge> edges;
    unordered_map<int, int> dist;
    
    // 读入边信息
    for (int i = 0; i < n; i++) {
        int s, e, w;
        cin >> s >> e >> w;
        edges.emplace_back(s, e, w);
        dist[s] = INT_MAX;
        dist[e] = INT_MAX;
    }
    
    // Bellman-Ford算法
    dist[0] = 0;
    while (true) {
        bool update = false;
        for (const Edge& e : edges) {
            if (dist[e.from] != INT_MAX && 
                dist[e.to] > dist[e.from] + e.weight) {
                dist[e.to] = dist[e.from] + e.weight;
                update = true;
            }
        }
        if (!update) break;
    }
    
    cout << (dist[end] == INT_MAX ? -1 : dist[end]) << endl;
    return 0;
}
import java.util.*;

public class Main {
    static class Edge {
        int from, to, weight;
        Edge(int from, int to, int weight) {
            this.from = from;
            this.to = to;
            this.weight = weight;
        }
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int end = sc.nextInt();
        int n = sc.nextInt();
        
        Edge[] edges = new Edge[n];
        Map<Integer, Integer> dist = new HashMap<>();
        
        // 读入边信息
        for (int i = 0; i < n; i++) {
            int s = sc.nextInt();
            int e = sc.nextInt();
            int w = sc.nextInt();
            edges[i] = new Edge(s, e, w);
            dist.put(s, Integer.MAX_VALUE);
            dist.put(e, Integer.MAX_VALUE);
        }
        
        // Bellman-Ford算法
        dist.put(0, 0);
        while (true) {
            boolean update = false;
            for (Edge e : edges) {
                if (dist.get(e.from) != Integer.MAX_VALUE && 
                    dist.get(e.to) > dist.get(e.from) + e.weight) {
                    dist.put(e.to, dist.get(e.from) + e.weight);
                    update = true;
                }
            }
            if (!update) break;
        }
        
        System.out.println(dist.get(end) == Integer.MAX_VALUE ? -1 : dist.get(end));
    }
}
class Edge:
    def __init__(self, from_node, to_node, weight):
        self.from_node = from_node
        self.to_node = to_node
        self.weight = weight

# 读入数据
end, n = map(int, input().split())
edges = []
dist = {}

# 读入边信息
for _ in range(n):
    s, e, w = map(int, input().split())
    edges.append(Edge(s, e, w))
    dist[s] = float('inf')
    dist[e] = float('inf')

# Bellman-Ford算法
dist[0] = 0
while True:
    update = False
    for e in edges:
        if (dist[e.from_node] != float('inf') and 
            dist[e.to_node] > dist[e.from_node] + e.weight):
            dist[e.to_node] = dist[e.from_node] + e.weight
            update = True
    if not update:
        break

print(-1 if dist[end] == float('inf') else dist[end])

算法及复杂度

  • 算法:Bellman-Ford最短路径算法
  • 时间复杂度: - 为顶点数, 为边数
  • 空间复杂度: - 需要存储到每个顶点的距离