解题思路:比赛的是没读懂题意,这题求的是起点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 + 记忆化搜索)的更多相关文章

  1. JavaScript对列表节点的操作:删除指定节点、删除最后一个节点、删除第一个节点、删除所有节点、增加节点

    使用菜鸟的运行环境直接测试:http://www.runoob.com/try/try.php?filename=tryjs_events <!DOCTYPE html> <html ...

  2. Redis Cluster 强制kill某一个节点和shutdown某一个节点后修复过程

    redis cluster 命令行,执行以下命令需登录cluster,是集群所独有的集群(cluster)CLUSTER INFO 打印集群的信息CLUSTER NODES 列出集群当前已知的所有节点 ...

  3. 剑指offer-08 二叉树的下一个节点

    剑指offer第8题,本来想找leetcode上对应的题,后来没找到,直接去牛客网上刷了. 题目描述: 给定一个二叉树和其中的一个结点(pNode),请找出中序遍历顺序的下一个结点并且返回.注意,树中 ...

  4. 剑指offer 面试题8:二叉树的下一个节点

    题目:给定一棵二叉树和其中一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左.右节点的指针,还有一个节点指向父节点的指针. 中序遍历序列是{d,b,h,e,i,a,f,c,g} ...

  5. 【剑指offer】08二叉树的下一个节点,C++实现

    原创博文,转载请注明出处! # 题目 父节点指向子节点的指针用实线表示,从子节点指向父节点的指针用虚线表示. # 思路 如果节点有右子节点,则右子节点的最左节点是该节点的下一个节点.例如,寻找b的下一 ...

  6. 【剑指 Offer】08.二叉树的下一个节点

    题目描述 给定一颗二叉树和其中的一个节点,找出中序遍历序列的下一个节点.树中的节点除了有两个分别指向左右节点的指针,还有一个指向父节点的指针. Java public class Solution08 ...

  7. 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。

    /** 转换成XML格式字符串 **/ public static String doXMLStr(Map<String, String> map) { StringBuffer xml_ ...

  8. [LeetCode 116 117] - 填充每一个节点的指向右边邻居的指针I & II (Populating Next Right Pointers in Each Node I & II)

    问题 给出如下结构的二叉树: struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } ...

  9. JavaScript---网络编程(7)-Dom模型(节点间的层次关系,节点的增、删、改)

    利用节点间的层次关系获取节点: 上一节讲了3中获取的方式: * ※※一.绝对获取,获取元素的3种方式:-Element * 1.getElementById(): 通过标签中的id属性值获来取该标签对 ...

  10. hdoj 2196 Computer【树的直径求所有的以任意节点为起点的一个最长路径】

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

随机推荐

  1. CodeForces 1324F Maximum White Subtree

    题意 给定一棵\(n\)个节点的无根树,每个节点为黑色或者白色,每个点的答案为包含该点的子树(指无根子树)的白色节点数减黑色节点数的最大值 分析 对于无根树的题一般指定某一个点为根,不妨设为\(1\) ...

  2. 文心一言 VS 讯飞星火 VS chatgpt (87)-- 算法导论8.2 4题

    四.用go语言,设计一个算法,它能够对于任何给定的介于0到 k 之间的 n 个整数先进行预处理,然后在 O(1)时间内回答输入的 n个整数中有多少个落在区间[a..b]内.你设计的算法的预处理时间应为 ...

  3. 如何将GitLab仓库同步到GitHub和Gitee?

    作者:西瓜程序猿 主页传送门:https://www.cnblogs.com/kimiliucn 前言 在之前写的[Kimi.RocketMQ.NET]开源项目中,代码我是放在自己搭建的GitLab服 ...

  4. Lua5.3 笔记

    Lua5.3 笔记 最近用skynet,sproto通讯,完全看不懂通讯二进制是怎么写的,发现都是string这个,string那个,完全理解不来. 于是查了一下string.pack的api,和之前 ...

  5. 关于oop的一点回忆

    昨天在一个程序员行业群里看到别人发了一条消息, 大意是:要做好封装啦,不要随便用public啦,不要随便改别人代码啦. 说的好像就是我,因为,我这辈子最后悔的一件事情之一就是手贱改动别人代码. 那大概 ...

  6. 图解Spark排序算子sortBy的核心源码

    原创/朱季谦 一.案例说明 以前刚开始学习Spark的时候,在练习排序算子sortBy的时候,曾发现一个有趣的现象是,在使用排序算子sortBy后直接打印的话,发现打印的结果是乱序的,并没有出现完整排 ...

  7. App性能指标(安装、冷启动、卸载、平均内存/cpu/fps/net)测试记录

    [需求背景] 需要针对产品以及竞品做出横向对比,输出对应的比对测试报告,供产研进行产品性能优化依据 [测试方案] 对于主流的厂商和系统版本进行多维度的横向对比 厂商:华为系.小米系.蓝绿系.三星系.苹 ...

  8. 【matplotlib 实战】--堆叠面积图

    堆叠面积图和面积图都是用于展示数据随时间变化趋势的统计图表,但它们的特点有所不同.面积图的特点在于它能够直观地展示数量之间的关系,而且不需要标注数据点,可以轻松地观察数据的变化趋势.而堆叠面积图则更适 ...

  9. 安装vscode

    1.下载vscode安装包 因为vscode官网下载太慢, 所以从360的软件库下载: https://baoku.360.cn/soft/search?kw=vscode 2.直接点击安装 3.设置 ...

  10. umich cv-3-1

    UMICH CV Neural Network 对于传统的线性分类器,分类效果并不好,所以这节引入了一个两层的神经网络,来帮助我们进行图像分类 可以看出它的结构十分简单,x作为输入层,经过max(0, ...