【Fifty Project - D28】
今日完成记录
Time | Plan | 完成情况 |
---|---|---|
9:30 - 11:30 | Leetcode | √ |
14:00 - 15:30 | 练胸 | √ |
15:30 - 16:30 | Leetcode | √ |
19:40 - 21:20 | 有氧 | √ |
Leetcode
今天是周赛复盘篇,昨天的周赛太刺激了,最后一分钟改好了bug拿下第三题,浅浅上分了,不过说到底还是自己太菜了,昨天的难度也是明显下降了一些。
学习了0x3f大佬的周赛讲解,主要针对第三和第四题进行详细的学习。
0-1BFS
网格传送门旅游:有一个地图,目标是从左上角走到左下角,其中会有一些传送门,在图中标识为大写字母,相同的大写字母之间可以实现无费用的传送,但是一种传送门最多只能使用一次;还有一些墙“#”。每次移动可以走上下左右四个方向。求最小移动次数。
思路1:如果不看传送门,那么就是一个普通的最短路问题,结合传送门,题目给出了一种传送门只能使用一次这个限制,其实如果是计算最短路,每种传送门就应该是最多用一次,这个不能算限制,算是一个tip,使用一个status存是否使用过传送门的状态,使用过后续就不再使用。其余的就和普通的最短路是一样的(Dijstract算法)
周赛的时候也只能想到这个方法,但是这个方法复杂度高一点,因为其中用堆来选取下一步,所以复杂度是O(nlogn) 灵茶山给了一个0-1BFS的思路
思路2:传送门可以视作一个权重为0的通路,其他向相邻节点的移动则视作权重为1的通路,直接从起点BFS。和普通的bfs走迷宫(权重均为1)的区别就是,其中可以传送,传送不消耗费用,因此维护当前队列,不能一味地往队尾加下一个节点,遇到能传送的点的时候,应该直接向队头插入所有可传送的点。其中也需要用一个状态记录是否走过传送门。
树上倍增算法以及LCA
包含给定路径的最小带权子树III:题目首先给了一棵树,然后有m次查询,每次查询由三个节点组成,要求返回能联通这三个节点的最小子树的权重。如下图:最小子树是节点1、2、3、4,权重和是12
思路:首先思考更简单的情况,只考虑求联通两个节点的最小子图权重和,不难发现其实就是找到两个节点的最近公共祖先(Lowest common ancestor, LCA),然后计算LCA到两个节点的路径和。LCA可以用树上倍增算法求解,路径和可以使用一次dfs,计算所有节点的深度、根到节点的费用。之后计算点到LCA的路径权重只需要做一次减法即可(当前节点到根节点费用减去LCA到根节点费用),至此,简单的两个节点的情况就可以解决了。
从两个点拓展到三个点,如下图:两个点时最小子图的权重和等于LCA(2,3),三个点时(2,3,4)最小子图的权重和等于(LCA(2,3) + LCA(3,4)+ LCA(4,2))/ 2。
实际上,这个问题还可以拓展到联通K个节点的最小子图,结论即:最小子图权重和为绕着这k个节点走一圈的费用除以二(绕着走一圈的费用可以使用LCA求解),其中必须要满足绕一圈,也就是需要根据某种顺序进行LCA求解,如下图5个节点的情况,左边遍历顺序是5-2-3-4-0-5,右边遍历顺序是2-3-5-4-0-2,可以看出右边途中1-2段走了四次,因此在四个节点以及四个节点以上,是需要考虑遍历顺序的,也就是必须恰好不走多余路情况下绕一圈。
这里解释一下为什么是四个节点以及以上,三个节点为啥不用考虑顺序
因为三个节点(a,b,c)的情况下能出现的情况有a-b-c-a, b-c-a-b, c-a-b-c, a-c-b-a, b-a-c-b, c-b-a-c。其中前三个相互等价,后三个相互等价,只是起点不同。那么如果情况1(a-b-c-a)和情况4(a-c-b-a)等价,那么说明所有情况等价。情况1中走一圈的代价total = lca(a,b) + lca(b,c) + lca(c, a),情况4中走一圈的代价total = lca(a,c) + lca(c,b) + lca(b, a)。可见两个式子相等(其中lca指的是通过lca算法计算联通这两个节点的最小代价),因为只有三个点,这六种情况其实无非对应的是顺时针走圈还是逆时针走圈,所以不会出现重复边的问题。而当点大于3个的时候,不按照一定顺序绕圈,则可能出现重复边情况。
如何得到一个不重复边的绕边方案呢?
答:使用先序遍历或者后序遍历给所有节点编号,按照编号逐个访问。
健身
周一练胸日:
- 史密斯平板卧推 50-60-70-70kg * 12
- 史密斯上斜卧推 40-50-50-50kg * 12
- 蝴蝶机夹胸 25-35-35-30kg * 12
- 直臂下压 10-12.5-15-15kg * 12
- 悬垂举腿 10-8-8-6次