解题思路:比赛的是没读懂题意,这题求的是起点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. 遗传算法解决航路规划问题(MATLAB)

    遗传算法 文章部分图片和思路来自司守奎,孙兆亮<数学建模算法与应用>第二版 定义:遗传算法是一种基于自然选择原理和自然遗传机制的搜索(寻优)算法,模拟自然界中的声明进化机制,在人工系统中实 ...

  2. Linux下导入MySQL数据库

    导入数据库1.首先建空数据库mysql>create database abc; 2.导入数据库方法一:(1)选择数据库mysql>use abc;(2)设置数据库编码mysql>s ...

  3. 通过snmp获取设备每个接口的配置IP地址,网段信息和VLAN接口号

    第一部分,观察通过snmp OID能获取的信息,对信息进行关联. 1.通过 snmp获取到接口IP地址和掩码信息,发现IP地址作为索引值: 2.每个IP地址的索引,都可以关联到接口的索引 3.每个接口 ...

  4. 修改经过Spring Gateway的Json数据

    背景 使用Spring Cloud Gateway作为网关时经常会需要对报文内的json数据进行修改,但是目前看到的实现方法看起来都很复杂,这里提供一种使用Spring官方提供的ModifyReque ...

  5. 「codeforces - 1519E」Off by One

    link. 点 \(A\) 与 \((0,0)\),\(B\) 共线的充要条件是 \(\frac{y_A}{x_A}=\frac{y_B}{x_B}\),即 \(k_{OA}=k_{OB}\).又考虑 ...

  6. spark修改控制台输出日志级别

    spark修改控制台输出日志级别 修改conf/log4j.properties cd $SPARK_HOME/conf cp log4j.properties.template ./log4j.pr ...

  7. Android 通过solid来定义不同边框的颜色,可以只定义一个边框的颜色

    以下是设置按钮的右边框和底边框颜色为红色,边框大小为3dp,如下图: 在drawable新建一个 btnstyle.xml的文件,内容如下: <?xml version="1.0&qu ...

  8. gson如何序列化子类

    需求 目前有一个需求,不同对象有一些公共属性,分别也有一些不同的属性.对方传过来的json字符串中,把这些对象组成了一个数组返回过来的.这样该如何反序列化呢? 举例 定义Person类.Student ...

  9. Vue之style的用法

    Vue中style的用法总结如下: v-bind:style  简写:style 1.基本用法 <!DOCTYPE html> <html lang="en"&g ...

  10. 18.2 使用NPCAP库抓取数据包

    NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库.它是WinPcap库的一个分支,由Nmap开发团队开发,并在Nmap软件中使用.与WinPcap一样,NPCAP库提供了一些 ...