题意: 给 n 点 m 边的公交车站,我们可以选择 多个起点到达某个终点,那么求出我们到达终点的最短路。这样我们有两种思路:
第一:以每一个 自己的多个 出发点为起点去更新 我们的每个dist,这样我们的时间复杂度为: O((n*n )||(m*logn)*n)在一个for(1-n)中求多次dijkstra --TLE -- 不行 ;
第二: 反着看: 我们的目标只是求我们的多个出发点到朋友点的距离中的最小值,那么我们是否可以反着来呢--即求 终点到多个出发点的最小值,这样只需要求一次单元最短路--最大的O(n*n)也是可以过的!!!(问题得解,接下来只需要反向建边即可,套用单源最短路模板即可)
2.1131. 拯救大兵瑞恩 - AcWing题库
题意: 迷宫中找最短路: (多了钥匙限制--利用数位dp思想解决)
解法一:双端队列+bfs --优化djikstra求最短路
--考虑分为一种边长为0的边--头钥匙更新
--边长为1的边往4个方向走,dist+1
--0,1 边长 --双端队列bfs
解法二:普通的bfs(队列非空时不断出队,取队头元素,尝试向四个方向转移)--走完所有路
--并不用考虑要不要拿钥匙,拿钥匙又不会增加成本,只管拿就行
本体难点在于数据的处理:
1.二维化一维:
z= (x - 1) * m + y;
从0开始编号的话,x = z / m,y = z % m
从1开始编号的话x = (z - 1) / m + 1,y = (z - 1) % m + 1
2.掌握数位dp的思想 -- 开几个二维数组 使用 常量 1>>M 表示M种状态,s1|=s0 表示继承关系
1.先求出 全局最小值是多少
2.再分别求出每个子集中 等于 全局最小值的元素个数
怎么求出全局最小值 使用拓补图即可 -- 后面点的关系依赖于前面已经更新并且正确的点,
那么这样我们就考虑建立拓补树即可
注意:要求最短路计数首先满足条件是不能存在权值为0的环,因为存在的话那么被更新的点的条数就为INF了。
建立拓补树:dijkstra访问过的边和点拿出来就是拓扑树,因为不会回去更新,BFS同理
引入二维数组求次小值个数
注意: //小根堆重载 大于号 -//greater<ver> 这里面是用的大于号,所以要重载大于号