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 ...
随机推荐
- WPF学习 - 动画基础(2)
上一篇文章粗略的介绍了一下Animation类.本篇介绍一下Storyboard. Storyboard,姑且翻译成"故事板"吧.实际上它是一个Animation对象的容器,可以容 ...
- QA|如何给我们的自动化测试代码增加日志记录?|Loguru
这里我们用的是loguru,logging虽然是自带的,但确实使用起来比较繁琐,loguru在Logging基础上增加了很多个性化功能,使用起来也比较简单,所以就使用loguru 代码如下: 1 # ...
- vue + canvas 实现九宮格手势解锁器
前言 专栏分享:vue2源码专栏,vue router源码专栏,玩具项目专栏,硬核推荐 欢迎各位 ITer 关注点赞收藏 此篇文章用于记录柏成从零开发一个canvas九宮格手势解锁器的历程,最终效果如 ...
- 安卓APK加固工具 如何进行实名认证购买和激活
安卓APK资源混淆加密重签名工具 价格表 授权时长 价格 1小时 49 1天 99 1个月 199 1个季度 399 半年 599 1年 799 付费版功能 功能点 免费版 付费版 去除广告信息 × ...
- 485modbus转profinet网关连接威纶通与三菱变频器modbus通讯
485modbus转profinet网关连三菱变频器modbus通讯触摸屏监控 本案例介绍了如何通过485modbus转profinet网关连接威纶通与三菱变频器进行modbus通讯.485modbu ...
- paramiko免密登陆
paramiko免密登陆 # -*- coding: utf-8 -*- import paramiko pkey='D:/pycharm_workspace/testpy/ssh_paramiko_ ...
- spark修改控制台输出日志级别
spark修改控制台输出日志级别 修改conf/log4j.properties cd $SPARK_HOME/conf cp log4j.properties.template ./log4j.pr ...
- 前端三件套系例之CSS——CSS3基础样式
文章目录 1.宽和高 案例 2.字体属性 2-1 文字字体 2-2 字体大小 2-3 字重(粗细) 2-4 文本颜色 2-5 总结 2-6 案例 文字属性 3-1 文字对齐 3-2 文字装饰 3-3 ...
- CF339D
题目简化与分析: 题目翻译说的还是太复杂了,其实只是给你 $ n $ 个数,奇数位 \(\operatorname{or}\),偶数位 \(\operatorname{xor}\). 会修改某个元素 ...
- React-Admin后台管理模板|react18+arco+zustand后台解决方案
基于react18.x+vite4+arco-design自研中后台管理系统解决方案ReactAdmin. react-vite-admin 基于vite4搭建react18.x后台管理项目.使用了r ...

