2023.11.15 每日一题(AI自生成应用)【C++】【Python】【Java】【Go】 动态路径分析

目录

一、题目

二、解决方法

三、改进


一、题目

背景: 在一个城市中,有数个交通节点,每个节点间有双向道路相连。每条道路具有一个初始权重,代表通行该路段的成本(例如时间、费用等)。随着时间的变化,道路的权重可能会发生变化,比如由于交通堵塞或道路维修。

问题: 设计一个算法,以处理以下两种类型的查询:

  1. 更新查询:给定两个节点及新的权重值,更新这两个节点之间道路的权重。
  2. 最短路径查询:给定两个节点,找出这两个节点之间的最短路径及其权重。

输入格式

输出格式

  • 对于每个最短路径查询,输出一个整数,表示最短路径的权重。如果两个节点之间没有路径,则输出 -1

实际应用: 这个问题可以应用于交通管理系统,例如实时更新交通状况并为司机提供最优路线。也适用于网络数据流量管理,其中节点代表数据中心,道路代表连接它们的网络。

挑战

  • 设计一个高效的数据结构来存储和更新节点间的道路权重。
  • 实现一个算法来快速回答最短路径查询,考虑到道路权重可能频繁变化。

二、解决方法

解决:

为了解决这个动态路径分析问题,我们可以采用以下策略:

  1. 数据结构:使用邻接表来表示图,其中每个节点都有一个列表存储它与其他节点的连接及其权重。
  2. 路径更新:对于更新操作,我们只需要修改邻接表中对应的权重。
  3. 最短路径查询:使用 Dijkstra 算法来找到最短路径。由于权重可能会频繁变化,我们在每次查询时都从头开始执行 Dijkstra 算法。

C++实现:

#include <iostream>
#include <vector>
#include <queue>
#include <climits>using namespace std;typedef pair<int, int> pii; // pair of (weight, node)class Graph {int V; // Number of verticesvector<vector<pii>> adj; // Adjacency listpublic:Graph(int V) : V(V), adj(V) {}void addEdge(int u, int v, int w) {adj[u].push_back({w, v});adj[v].push_back({w, u}); // For undirected graph}void updateEdge(int u, int v, int w) {// Update weight for edge u-vfor (auto &p : adj[u]) {if (p.second == v) {p.first = w;break;}}for (auto &p : adj[v]) {if (p.second == u) {p.first = w;break;}}}int shortestPath(int source, int destination) {priority_queue<pii, vector<pii>, greater<pii>> pq;vector<int> dist(V, INT_MAX);pq.push({0, source});dist[source] = 0;while (!pq.empty()) {int u = pq.top().second;pq.pop();for (auto &[w, v] : adj[u]) {if (dist[v] > dist[u] + w) {dist[v] = dist[u] + w;pq.push({dist[v], v});}}}return (dist[destination] == INT_MAX) ? -1 : dist[destination];}
};int main() {int N, M, u, v, w;cin >> N >> M;Graph g(N);for (int i = 0; i < M; ++i) {cin >> u >> v >> w;g.addEdge(u, v, w);}// Querieschar queryType;while (cin >> queryType) {if (queryType == 'U') {cin >> u >> v >> w;g.updateEdge(u, v, w);} else if (queryType == 'Q') {cin >> u >> v;cout << g.shortestPath(u, v) << endl;}}return 0;
}

Python:

import heapqclass Graph:def __init__(self, V):self.V = Vself.graph = {i: {} for i in range(V)}def add_edge(self, u, v, w):self.graph[u][v] = wself.graph[v][u] = wdef update_edge(self, u, v, w):if v in self.graph[u]:self.graph[u][v] = wif u in self.graph[v]:self.graph[v][u] = wdef shortest_path(self, source, destination):dist = [float('inf')] * self.Vdist[source] = 0pq = [(0, source)]while pq:d, u = heapq.heappop(pq)if d > dist[u]:continuefor v, w in self.graph[u].items():if dist[u] + w < dist[v]:dist[v] = dist[u] + wheapq.heappush(pq, (dist[v], v))return dist[destination] if dist[destination] != float('inf') else -1# Example usage
g = Graph(N)  # N is the number of vertices
# Add edges and handle queries similarly to the C++ example

JAVA:

import java.util.*;public class Graph {private int V;private Map<Integer, Map<Integer, Integer>> adj;public Graph(int V) {this.V = V;this.adj = new HashMap<>();for (int i = 0; i < V; i++) {adj.put(i, new HashMap<>());}}public void addEdge(int u, int v, int w) {adj.get(u).put(v, w);adj.get(v).put(u, w);}public void updateEdge(int u, int v, int w) {if (adj.get(u).containsKey(v)) {adj.get(u).put(v, w);}if (adj.get(v).containsKey(u)) {adj.get(v).put(u, w);}}public int shortestPath(int source, int destination) {int[] dist = new int[V];Arrays.fill(dist, Integer.MAX_VALUE);dist[source] = 0;PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[1]));pq.add(new int[]{source, 0});while (!pq.isEmpty()) {int[] current = pq.poll();int u = current[0];if (u == destination) {break;}for (Map.Entry<Integer, Integer> entry : adj.get(u).entrySet()) {int v = entry.getKey();int weight = entry.getValue();if (dist[u] + weight < dist[v]) {dist[v] = dist[u] + weight;pq.add(new int[]{v, dist[v]});}}}return dist[destination] == Integer.MAX_VALUE ? -1 : dist[destination];}// Example usagepublic static void main(String[] args) {Graph g = new Graph(N); // N is the number of vertices// Add edges and handle queries similarly to the C++ example}
}

Go语言:

package mainimport ("container/heap""fmt""math"
)type Edge struct {node, weight int
}type Graph struct {V     intedges map[int]map[int]int
}func NewGraph(V int) *Graph {g := &Graph{V:     V,edges: make(map[int]map[int]int),}for i := 0; i < V; i++ {g.edges[i] = make(map[int]int)}return g
}
func (g *Graph) UpdateEdge(u, v, w int) {if _, ok := g.edges[u][v]; ok {g.edges[u][v] = w}if _, ok := g.edges[v][u]; ok {g.edges[v][u] = w}
}func (g *Graph) ShortestPath(source, destination int) int {dist := make([]int, g.V)for i := range dist {dist[i] = math.MaxInt32}dist[source] = 0pq := make(PriorityQueue, 0)heap.Init(&pq)heap.Push(&pq, &Item{value:    source,priority: 0,})for pq.Len() > 0 {item := heap.Pop(&pq).(*Item)u := item.valueif u == destination {break}for v, w := range g.edges[u] {if dist[u]+w < dist[v] {dist[v] = dist[u] + wheap.Push(&pq, &Item{value:    v,priority: dist[v],})}}}if dist[destination] == math.MaxInt32 {return -1}return dist[destination]
}// Define the priority queue used for Dijkstra's algorithm
type Item struct {value    int // The node indexpriority int // The node's priority (distance)index    int // The index of the item in the heap
}type PriorityQueue []*Itemfunc (pq PriorityQueue) Len() int { return len(pq) }func (pq PriorityQueue) Less(i, j int) bool {return pq[i].priority < pq[j].priority
}func (pq PriorityQueue) Swap(i, j int) {pq[i], pq[j] = pq[j], pq[i]pq[i].index = ipq[j].index = j
}func (pq *PriorityQueue) Push(x interface{}) {n := len(*pq)item := x.(*Item)item.index = n*pq = append(*pq, item)
}func (pq *PriorityQueue) Pop() interface{} {old := *pqn := len(old)item := old[n-1]old[n-1] = nilitem.index = -1*pq = old[0 : n-1]return item
}func main() {// Example usageg := NewGraph(N) // N is the number of vertices// Add edges and handle queries similarly to the C++ example
}

三、改进

  1. 效率问题:每次查询最短路径时都需要从头执行 Dijkstra 算法。在频繁更新边权重的场景中,这可能导致效率低下。
  2. 数据结构选择:现有实现使用邻接表来存储图,这对于稀疏图是合适的。但对于密集图,这种表示方式可能导致内存使用不经济。

改进:

  1. 增量更新算法:对于频繁更新的场景,可以考虑使用更高级的图算法,如“动态最短路径算法”。这类算法可以在不重新计算整个图的情况下,有效更新最短路径。
  2. 数据结构优化:针对不同类型的图(稀疏或密集),选择合适的数据结构。例如,对于密集图,可以使用邻接矩阵来代替邻接表。
#include <iostream>
#include <vector>
#include <queue>
#include <climits>using namespace std;const int MAX_V = 1000; // 假设图中最多有1000个节点class Graph {int V; // 顶点数vector<vector<int>> adjMatrix; // 邻接矩阵public:Graph(int V) : V(V), adjMatrix(V, vector<int>(V, INT_MAX)) {}void addEdge(int u, int v, int w) {adjMatrix[u][v] = w;adjMatrix[v][u] = w;}void updateEdge(int u, int v, int w) {adjMatrix[u][v] = w;adjMatrix[v][u] = w;}int shortestPath(int source, int destination) {vector<int> dist(V, INT_MAX);vector<bool> sptSet(V, false);dist[source] = 0;for (int count = 0; count < V - 1; count++) {int u = minDistance(dist, sptSet);sptSet[u] = true;for (int v = 0; v < V; v++) {if (!sptSet[v] && adjMatrix[u][v] != INT_MAX && dist[u] != INT_MAX &&dist[u] + adjMatrix[u][v] < dist[v]) {dist[v] = dist[u] + adjMatrix[u][v];}}}return (dist[destination] == INT_MAX) ? -1 : dist[destination];}private:int minDistance(const vector<int> &dist, const vector<bool> &sptSet) {int min = INT_MAX, min_index;for (int v = 0; v < V; v++) {if (!sptSet[v] && dist[v] <= min) {min = dist[v];min_index = v;}}return min_index;}
};int main() {// 示例用法int N, M, u, v, w;cin >> N >> M;Graph g(N);for (int i = 0; i < M; ++i) {cin >> u >> v >> w;g.addEdge(u, v, w);}// 处理查询// ...
}

        这个实现针对密集图进行了优化,但它不包括动态最短路径算法的实现。动态最短路径算法通常更复杂,可能需要使用更高级的数据结构和算法技巧。这种算法的实现和优化通常是图算法研究的前沿话题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/193524.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VirtualBox+Vagrant安装虚拟机

文章目录 一、下载Virtualbox和Vagrant1、下载2、安装 二、安装虚拟机1、新建目录D:\VirtualMachine2、执行vagrant init centos/7命令&#xff0c;就会在该目录下创建Vagrantfile文件3、执行vagrant up命令4、查看当前主机分给虚拟机的网关网段5、找到D:\VirtualMachine下的Va…

BUUCTF 九连环 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 下载附件&#xff0c;解压得到一张.jpg图片。 密文&#xff1a; 解题思路&#xff1a; 1、一张图片&#xff0c;典型的图片隐写。放到Kali中&#xff0c;使用binwalk检测&#xff0c;确认图片中隐藏zip压缩包。 使…

java初探之代理模式

代理模式 代理模式一般有三种角色&#xff1a; 没有使用代理模式的话可能就会直接去操作真实的对象 加入代理模式就是加入了 隔离 把我们的真实对象与调用者隔离了一下(代理对象) 代理对象的好处&#xff1f; 使用者(client)跟真实的对象是没有直接的交集的。不会直接操作到…

.Net8 Blazor 尝鲜

全栈 Web UI 随着 .NET 8 的发布&#xff0c;Blazor 已成为全堆栈 Web UI 框架&#xff0c;可用于开发在组件或页面级别呈现内容的应用&#xff0c;其中包含&#xff1a; 用于生成静态 HTML 的静态服务器呈现。使用 Blazor Server 托管模型的交互式服务器呈现。使用 Blazor W…

Games104现代游戏引擎笔记 面向数据编程与任务系统

Basics of Parallel Programming 并行编程的基础 核达到了上限&#xff0c;无法越做越快&#xff0c;只能通过更多的核来解决问题 Process 进程 有独立的存储单元&#xff0c;系统去管理&#xff0c;需要通过特殊机制去交换信息 Thread 线程 在进程之内&#xff0c;共享了内存…

后端接口错误总结

今天后端错误总结&#xff1a; 1.ConditionalOnExpression(“${spring.kafka.exclusive-group.enable:false}”) 这个标签负责加载Bean&#xff0c;因此这个位置必须打开&#xff0c;如果这个标签不打开就会报错 问题解决&#xff1a;这里的配置在application.yml文件中 kaf…

HelloWorld - 从Houdini导出HDA到UE5

1.配置插件 在Houdini安装目录下找到对应版本引擎的插件&#xff0c;例如这里是Houdini19对应UE5.2的版本&#xff0c;我们就要保证先下载好UE5.2&#xff1a; 将Houdini插件粘贴到UE安装目录的Plugins文件夹下&#xff1a; 目前插件配置完成&#xff0c;打开UE会自动启用插…

C与汇编深入分析

汇编怎么调用C函数 直接调用 BL main传参数 在arm中有个ATPCS规则&#xff08;ARM-THUMB procedure call standard&#xff09;&#xff08;ARM-Thumb过程调用标准&#xff09;。 约定r0-r15寄存器的用途&#xff1a; r0-r3&#xff1a;调用者和被调用者之间传递参数r4-r11…

【python】Django——django简介、django安装、创建项目、快速上手

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 【Django专栏】 Django——django简介、django安装、创建项目、快速上手 Django——templates模板、静态文件、django模板语法、请求和响应 Django——连接mysql数据库 Django——django安装、创建django项目、dj…

提高生存能力的7个关键技巧!

作为一款备受热议和玩家喜爱的多人在线射击游戏&#xff0c;《绝地求生》中生存能力的提高是取得胜利的关键。在这篇实用干货分享中&#xff0c;我们将详细说明7个关键技巧&#xff0c;帮助你在游戏中提高生存能力&#xff0c;获得更多胜利。 1.选择降落点&#xff1a;选择适合…

Typora使用教程

文章目录 markdown的使用说明一、标题 这是一级标题这是二级标题二、段落1、换行2、分割线 三、文字显示1、字体2、上下标 四、列表1、无序列表2、有序列表3、任务列表 五、区块显示六、代码显示1、行内代码2、代码块 七、链接八、脚注九、图片插入十、表格十一、流程图1、横向…

excel怎么能保证粘贴公式的时候不自增

例如在C4单元格中输入了公式&#xff1a; 现在如果把C4拷贝到C5&#xff0c;D3会自增长为D4&#xff1a; 现在如果想拷贝的时候不自增长&#xff0c;可以先把光标放到C4单元格&#xff0c;然后按F4键&#xff0c;加上了$符号&#xff0c;锁定了&#xff1a; 现在再拷贝&a…

kubernetes资源管理

资源管理 资源管理介绍 在kubernetes中&#xff0c;所有的内容都抽象为资源&#xff0c;用户需要通过操作资源来管理kubernetes。 kubernetes的本质上就是一个集群系统&#xff0c;用户可以在集群中部署各种服务&#xff0c;所谓的部署服务&#xff0c;其实就是在kubernetes集…

人均年薪70万!华为项目经理具备了哪些能力

大家好&#xff0c;我是老原。 最近在逛脉脉的时候&#xff0c;看到了一位华为项目经理晒出的月收入&#xff1a;5W&#xff0c;这还是不包含每年分红奖励前的到手薪资。 按他现在的19级别&#xff0c;再加上分红奖励&#xff0c;年薪至少在70W&#xff0c;留言区羡慕声一片。…

Since Maven 3.8.1 http repositories are blocked

原因 高版本的maven不支持http的存储库。 解决方案 其实方法有好几种&#xff0c;比如降级maven版本至3.6.3(之前一直用的都是这个版本)&#xff0c;我选择了一种比较快(但不一定安全)的方式&#xff0c;因为3.6.3版本被我卸载了&#xff0c;这里直接修改idea的setting配置&…

【数据处理】Python:实现求条件分布函数 | 求平均值方差和协方差 | 求函数函数期望值的函数 | 概率论

猛戳订阅&#xff01; &#x1f449; 《一起玩蛇》&#x1f40d; &#x1f4ad; 写在前面&#xff1a;本章我们将通过 Python 手动实现条件分布函数的计算&#xff0c;实现求平均值&#xff0c;方差和协方差函数&#xff0c;实现求函数期望值的函数。部署的测试代码放到文后了&…

DNS正向解析和主从复制

目录 概念 DNS解析 例&#xff1a;www.baidu.com. 解析过程 DNS查询方式 DNS的查询过程 DNS软件bind 正向解析&#xff08;根据域名查找ip地址&#xff09; 1.先安装bind软件 2.打开网卡配置文件 将DNS1改为自己本机 &#xff08;更改完配置重启服务&#xff09; 3.打…

最长上升子序列模型 笔记

首先附上模板&#xff1a; #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing namespace std;typedef pair<int, int> PII; typedef long long ll;const int N 100010;int n; int a[N], q[N];int main()…

MySQL库的操作『增删改查 ‖ 编码问题 ‖ 备份与恢复』

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; MySQL 学习 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 &#x1f381;软件版本&#xff1a; MySQL 5.7.44 文章目录 1.创建数据库2.数据库中的编码问题2.1.字符集与校验集2.3.支持的字符…

DNS域名解析服务

1.概述 1.1.产生原因 IP 地址:是互联网上计算机唯一的逻辑地址&#xff0c;通过IP 地址实现不同计算机之间的相互通信&#xff0c;每台联网计算机都需要通过I 地址来互相联系和分别&#xff0c;但由于P 地址是由一串容易混淆的数字串构成&#xff0c;人们很难记忆所有计算机的…