题解 | 旅途

旅途

https://www.nowcoder.com/practice/afe4e7f5f3b14ae9bd920cfb42056e28

解题思路

这是一个最短路径问题。需要找到从起点到终点被搭讪次数最少的路径。

关键点:

  1. 每个节点的权重是该站点的搭讪次数
  2. 路径的总权重是经过所有站点的搭讪次数之和
  3. 需要考虑起点和终点的搭讪次数
  4. 使用 算法求最短路径

算法步骤:

  1. 建立邻接表表示图
  2. 初始化距离数组
  3. 使用优先队列优化的 算法
  4. 返回到终点的最短距离

代码

#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    int shortestPath(int n, vector<int>& harassment, vector<vector<int>>& roads) {
        // 建立邻接表
        vector<vector<pair<int, int>>> graph(n + 1);
        for (const auto& road : roads) {
            int u = road[0], v = road[1];
            // 边的权重为目标站点的搭讪次数
            graph[u].push_back({v, harassment[v-1]});
            graph[v].push_back({u, harassment[u-1]});
        }
        
        // 距离数组,初始化为无穷大
        vector<int> dist(n + 1, INT_MAX);
        dist[1] = harassment[0];  // 起点的搭讪次数
        
        // 优先队列,存储{距离, 节点}
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
        pq.push({dist[1], 1});
        
        while (!pq.empty()) {
            auto [d, u] = pq.top();
            pq.pop();
            
            if (d > dist[u]) continue;
            
            // 遍历相邻节点
            for (auto [v, w] : graph[u]) {
                if (dist[v] > dist[u] + w) {
                    dist[v] = dist[u] + w;
                    pq.push({dist[v], v});
                }
            }
        }
        
        return dist[n];
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    
    vector<int> harassment(n);
    for (int i = 0; i < n; i++) {
        cin >> harassment[i];
    }
    
    vector<vector<int>> roads(m, vector<int>(2));
    for (int i = 0; i < m; i++) {
        cin >> roads[i][0] >> roads[i][1];
    }
    
    Solution solution;
    cout << solution.shortestPath(n, harassment, roads) << endl;
    
    return 0;
}
import java.util.*;

class Solution {
    public int shortestPath(int n, int[] harassment, int[][] roads) {
        // 建立邻接表
        List<List<int[]>> graph = new ArrayList<>(n + 1);
        for (int i = 0; i <= n; i++) {
            graph.add(new ArrayList<>());
        }
        
        // 添加边
        for (int[] road : roads) {
            int u = road[0], v = road[1];
            // 边的权重为目标站点的搭讪次数
            graph.get(u).add(new int[]{v, harassment[v-1]});
            graph.get(v).add(new int[]{u, harassment[u-1]});
        }
        
        // 距离数组,初始化为无穷大
        int[] dist = new int[n + 1];
        Arrays.fill(dist, Integer.MAX_VALUE);
        dist[1] = harassment[0];  // 起点的搭讪次数
        
        // 优先队列,存储{距离, 节点}
        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
        pq.offer(new int[]{dist[1], 1});
        
        while (!pq.isEmpty()) {
            int[] curr = pq.poll();
            int d = curr[0], u = curr[1];
            
            if (d > dist[u]) continue;
            
            // 遍历相邻节点
            for (int[] next : graph.get(u)) {
                int v = next[0], w = next[1];
                if (dist[v] > dist[u] + w) {
                    dist[v] = dist[u] + w;
                    pq.offer(new int[]{dist[v], v});
                }
            }
        }
        
        return dist[n];
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        
        int[] harassment = new int[n];
        for (int i = 0; i < n; i++) {
            harassment[i] = sc.nextInt();
        }
        
        int[][] roads = new int[m][2];
        for (int i = 0; i < m; i++) {
            roads[i][0] = sc.nextInt();
            roads[i][1] = sc.nextInt();
        }
        
        Solution solution = new Solution();
        System.out.println(solution.shortestPath(n, harassment, roads));
        
        sc.close();
    }
}
from heapq import heappush, heappop
from collections import defaultdict
from typing import List

class Solution:
    def shortest_path(self, n: int, harassment: List[int], roads: List[List[int]]) -> int:
        # 建立邻接表
        graph = defaultdict(list)
        for u, v in roads:
            # 边的权重为目标站点的搭讪次数
            graph[u].append((v, harassment[v-1]))
            graph[v].append((u, harassment[u-1]))
        
        # 距离数组,初始化为无穷大
        dist = [float('inf')] * (n + 1)
        dist[1] = harassment[0]  # 起点的搭讪次数
        
        # 优先队列,存储(距离, 节点)
        pq = [(dist[1], 1)]
        
        while pq:
            d, u = heappop(pq)
            
            if d > dist[u]:
                continue
            
            # 遍历相邻节点
            for v, w in graph[u]:
                if dist[v] > dist[u] + w:
                    dist[v] = dist[u] + w
                    heappush(pq, (dist[v], v))
        
        return dist[n]

def main():
    n, m = map(int, input().split())
    harassment = list(map(int, input().split()))
    
    roads = []
    for _ in range(m):
        u, v = map(int, input().split())
        roads.append([u, v])
    
    solution = Solution()
    print(solution.shortest_path(n, harassment, roads))

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法: 最短路径算法
  • 时间复杂度:,其中 是顶点数, 是边数
  • 空间复杂度:,用于存储图和距离数组
全部评论

相关推荐

04-16 10:27
已编辑
美团_Saas_后端开发
今天周一休息,突发奇想写一篇阶段总结。如题,我已经去了一个和Java彻底毫无关联的行业。曾经我以为自己能在计算机行业发光发热,拿到美团offer那会感觉自己天都亮了。没想到刚入行一年多就当了逃兵。从最开始的热爱到现在一看到代码就厌恶,不知道自己经历了什么。所以我去干什么了?答案是:在成都当了租房销售。上班那会压力大了就念叨着去干租房中介,但是一直下不去这个决心,想着自己学了四年多的计算机知识,终究还是不甘心。终于在某一天准备八股文的时候,看着无数篇和工作内容关系不大的理论知识,那一刻下定决心,决定尝试一下销售行业,也算是给自己一个交代。后面阴差阳错的投了成都自如去当租房管家,没想到面试很顺利,在当天一百多个面试的人里面,我成为了为数不多通过的几个幸运儿之一。目前已经培训通过,正式入职,也开了单,有压力但是每天过得很开心,真心喜欢那种和人交流的感觉,哪怕是最后没有选择找我租房。说这些也是想告诉那些大三,大四正在找Java实习而焦虑的同学:你们现在还年轻,选择很多,容错率也很高,可以尽情去尝试自己喜欢的行业和工作。不用因为某一次的面试没通过或者简历石沉大海而焦虑,更不用因为身边人都在挤编程的独木桥就强迫自己跟风。也算是自己的碎碎念吧,也希望自己能在新的领域取得一点小成就。也祝牛油工作顺利!
沉淀小子:干啥都不丢人啊,生存是必须要的,销售很考验一个人综合素质能力的,好的销售人脉和资源可不比写字楼的白领差啊
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务