LeetCode1786:从第一个节点出发到最后一个节点的受限路径数(dijkstra + 记忆化搜索)
解题思路:比赛的是没读懂题意,这题求的是起点1到n路径序列数,但是路径序列上的相邻两个点 i, i+1 之间应该满足 i、i+1 到终点的最短路low[i] > low[i+1]。
因此需要先以终点开始,跑一遍dijkstra算法,考虑时间复杂度,使用邻接表加优先队列优化。计算得到最短路 low 数组,从起点dfs到终点的路径数量,对于 i 节点,它到终点的路径数 dp[i] = sum(dp[ j ]) ( j 是满足受限条件的下一个节点 j,dp[j] 表示 j 到终点的路径数);考虑到得数需要模1e7+7,因此可能会重复访问某个节点,因此用dp[i] 数组保存节点 i 到终点的路径数,减少重复的dfs次数。
(ps:用python写的代码似乎有递归深度的限制,在一番折腾无解后,我用栈模拟了 dfs 过程。)
1 class Node(object):
2 def __init__(self,x,y):
3 self.id = x
4 self.dis = y
5
6 def __lt__(self, other): #定义了<,像C++的重载<运算符
7 return self.dis<other.dis
8
9
10 import heapq
11 class PriorityQueue(object):
12 def __init__(self):
13 self._queue = []
14 self._index = 0
15 def push(self, item, priority):
16 # 传入两个参数,一个是存放元素的数组,另一个是要存储的元素,这里是一个元组。
17 # 由于heap内部默认有小到大排,如果要从大到小排,就要对priority取负数
18 heapq.heappush(self._queue, (priority, self._index, item))
19 self._index += 1
20 def pop(self):
21 return heapq.heappop(self._queue)[-1]
22 def empty(self):
23 return not bool(len(self._queue))
24
25 class Solution(object):
26 def dij(self,n,vec):
27 inf = int(1e9)
28 used = [0]*n
29 low = [inf]*n
30 for i in range(n):
31 low[i] = inf
32 low[-1]=0
33 pq = PriorityQueue()
34 start = n-1
35 pq.push(start,low[n-1])
36 x= 0
37 while not pq.empty():
38 if x>=n:
39 break
40 now = pq.pop()
41 x+=1
42 #print(now.id)
43 for nxt in vec[now]:
44 if low[nxt.id] > low[now] + nxt.dis:
45 low[nxt.id] = low[now] + nxt.dis
46 pq.push(nxt.id,low[nxt.id])
47
48 return low
49
50 def countRestrictedPaths(self, n, edges):
51 sys.setrecursionlimit(100000)
52 inf = int(1e9)
53 vec = [[] for i in range(n)]
54 for edge in edges:
55 [s1,s2,w] = edge
56 n1,n2 = Node(s2-1,w),Node(s1-1,w)
57 vec[s1-1].append(n1)
58 vec[s2-1].append(n2)
59 #print(dis)
60 low = self.dij(n,vec)
61 #print('aaa')
62 dp = [0]*n
63 used = [0]*n
64 used[0] = 1
65 stack = [0]
66 while len(stack) >0:
67 top = stack.pop()
68 #print(stack)
69 stack.append(top)
70 if top == n-1: #终止条件
71 _ = stack.pop()
72 dp[top] = 1
73 used[top] = 0
74 continue
75 cnt = 0
76 flag = True
77 for nxt in vec[top]:
78 i = nxt.id
79 if low[top] > low[i] and used[i]==0:
80 if dp[i] == 0: #说明没有访问过,加入栈
81 #print('aaa',i)
82 used[i]=1
83 stack.append(i)
84 flag = False
85 break
86 else:
87 cnt= (cnt+dp[i])%(inf+7)
88 if not flag: #说明要继续搜索,当前状态不弹出
89 continue
90 dp[top] = cnt #记忆
91 _ = stack.pop()
92 used[top]=0
93 #print(self.dp)
94 #print(low)
95 return dp[0]
LeetCode1786:从第一个节点出发到最后一个节点的受限路径数(dijkstra + 记忆化搜索)的更多相关文章
- JavaScript对列表节点的操作:删除指定节点、删除最后一个节点、删除第一个节点、删除所有节点、增加节点
使用菜鸟的运行环境直接测试:http://www.runoob.com/try/try.php?filename=tryjs_events <!DOCTYPE html> <html ...
- Redis Cluster 强制kill某一个节点和shutdown某一个节点后修复过程
redis cluster 命令行,执行以下命令需登录cluster,是集群所独有的集群(cluster)CLUSTER INFO 打印集群的信息CLUSTER NODES 列出集群当前已知的所有节点 ...
- 剑指offer-08 二叉树的下一个节点
剑指offer第8题,本来想找leetcode上对应的题,后来没找到,直接去牛客网上刷了. 题目描述: 给定一个二叉树和其中的一个结点(pNode),请找出中序遍历顺序的下一个结点并且返回.注意,树中 ...
- 剑指offer 面试题8:二叉树的下一个节点
题目:给定一棵二叉树和其中一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左.右节点的指针,还有一个节点指向父节点的指针. 中序遍历序列是{d,b,h,e,i,a,f,c,g} ...
- 【剑指offer】08二叉树的下一个节点,C++实现
原创博文,转载请注明出处! # 题目 父节点指向子节点的指针用实线表示,从子节点指向父节点的指针用虚线表示. # 思路 如果节点有右子节点,则右子节点的最左节点是该节点的下一个节点.例如,寻找b的下一 ...
- 【剑指 Offer】08.二叉树的下一个节点
题目描述 给定一颗二叉树和其中的一个节点,找出中序遍历序列的下一个节点.树中的节点除了有两个分别指向左右节点的指针,还有一个指向父节点的指针. Java public class Solution08 ...
- 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
/** 转换成XML格式字符串 **/ public static String doXMLStr(Map<String, String> map) { StringBuffer xml_ ...
- [LeetCode 116 117] - 填充每一个节点的指向右边邻居的指针I & II (Populating Next Right Pointers in Each Node I & II)
问题 给出如下结构的二叉树: struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } ...
- JavaScript---网络编程(7)-Dom模型(节点间的层次关系,节点的增、删、改)
利用节点间的层次关系获取节点: 上一节讲了3中获取的方式: * ※※一.绝对获取,获取元素的3种方式:-Element * 1.getElementById(): 通过标签中的id属性值获来取该标签对 ...
- hdoj 2196 Computer【树的直径求所有的以任意节点为起点的一个最长路径】
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
随机推荐
- 数据可视化【原创】vue+arcgis+threejs 实现海量建筑物房屋渲染,性能优化
本文适合对vue,arcgis4.x,threejs,ES6较熟悉的人群食用. 先报备一下版本号 "vue": "^2.6.11" "@arcgis/ ...
- Java NIO 图解 Netty 服务端启动的过程
一.启动概述 了解整体Netty常用的核心组件后,并且对比了传统IO模式.在对比过程中,找到了传统IO对应Netty中是如何实现的.最后我们了解到在netty中常用的那些组件. 本文在了解下这些核心组 ...
- QA|如何实现一个函数读取1-9按钮?|网页计算器自动化测试实战
如何实现一个函数读取1-9按钮? 如何实现一个根据我们Json存的数字,自动选取对应按钮点击,并且点击对应算法? 首先我们肯定不能给每个元素都写一个函数吧,毕竟挺多,而且如果这样写了,那加减乘除都要分 ...
- crontab定时任务不执行的一些原因总结
参考博文地址: https://www.jb51.net/article/154290.htm声明:本文章是在以上地址博文基础上进行整理学习,如有侵权,请联系博主删除,感谢知识共享,一起进步,加油鸭 ...
- 2023版:深度比较几种.NET Excel导出库的性能差异
引言 背景和目的 本文介绍了几个常用的电子表格处理库,包括EPPlus.NPOI.Aspose.Cells和DocumentFormat.OpenXml,我们将对这些库进行性能测评,以便为开发人员提供 ...
- 其它——ZeroRPC和SimpleXMLRPCServer
文章目录 一 Python中RPC框架 二 SimpleXMLRPCServer使用 服务端 客户端 三 ZeroRPC使用 服务端 客户端 一 Python中RPC框架 自带的:SimpleXMLR ...
- Docker系列——介绍、安装、镜像、容器、docker容器与镜像、数据卷、Dockerfile、docker 配置pycharm连接
目录 1 Docker 介绍 1.1 简介 1.2 Docker平台介绍 1.3 为什么使用Docker 2 Docker 整体结构(了解) 2.1 Docker引擎介绍 (Docker Engine ...
- Django-rest-framework框架——Xadmin的使用、Book系列多表群操作、RBAC-基于角色的访问控制
@ 目录 一 过滤Filtering 二 排序 三 分页Pagination 可选分页器 应用 四 异常处理 Exceptions 4.1 使用方式 4.2 案例 4.3 REST framework ...
- 探索Redis与MySQL的双写问题
本文已收录至GitHub,推荐阅读 Java随想录 微信公众号:Java随想录 原创不易,注重版权.转载请注明原作者和原文链接 目录 双写一致问题 缓存读写策略 Cache-Aside Pattern ...
- 6.使用leetcode去练习语言
目录 1 本章预览 2 简单题举例 2.1 题目描述 2.2 题目解析 2.3 题解 2.4 涉及基础语法 3 中等题举例 3.1 题目描述 3.2 题目解析 3.3 题解 3.4 涉及基础语法 4 ...

