最短路
为了多水几篇博客,咱不全发。
合眼(安详
最短路
题意:
\(n\)个点,\(m\)条有向边,第一次经过点\(i\)需要付出\(p_i\)的代价,求从\(1\)到\(n\)再返回\(1\)所需的最小代价,无解输出\(-1\)。
解题思路:
如果重复经过某个点仍然需要付出代价,我们可以用最短路从\(1\)跑到\(n\)再从\(n\)跑到\(1\)直接搞。然而现在加上了这个条件,我们就必须考虑启程与归程形成一个环的时候经过了哪些点,总共付出了多少代价,把环拆成链先后跑两次最短路的想法是不合理的(原因显然),所以我们选择同时跑最短路。
对该图建一个反图,这样我们就能从\(1\)节点同时开始计算启程与归程。用\(dis_{i,j}\)来表示启程到了\(i\)节点,归程到了\(j\)节点时的最少代价,用\(path_{i,j,k}\)来记录启程到了\(i\)节点,归程到了\(j\)节点时,是否经过了\(k\)节点,如果没有经过,答案就要加上\(p_k\),同时需要使用\(vis_{i,j}\)来记录当前状态是否已经拓展过。
结果即为\(dis_{n,n}\)
那一天她哼哼啊啊啊啊啊啊啊啊啊
题意:
\(n\)个点,\(m\)条无向边,每条边都带边权,以\(1\)号节点为出发点,不能重复经过同一条边,求从出发点到出发点的最小环,无解输出\(-1\)。
解题思路:
这里提供两种:
-
考虑先使用\(dijkstra\)以出发点跑单源最短路,然后再从出发点暴力找出能成为最优答案的路径(使用估价函数),即,设\(w\)为从\(1\)走到\(u\)的答案,\(u\)为此时所在的节点,若\(w+dis[u]>ans\),则直接返回。
容易想出,最小环一定由出发点到某点的最短路和非严格次短路组成,当前情况下加上最短路的答案都会劣于已有答案,那么此时加上严格次短路的答案就一定劣于已有答案,可以直接返回。
-
考虑二进制优化建图(难绷),发现,启程和归程不可能都会经过与出发点相连的同一条边,也就是说,启程与归程中,与出发点相连的点的编号一定不同,那么它们按位异或的结果一定不为\(0\)。
那么就考虑记录下来与出发点直接相连的所有点的编号且不建边,枚举编号二进制的每一位,相同的不建,不同的建边跑最短路更新答案,所有的情况一定能被更新到,于是答案就出来力。
然后第一种思路会\(T\)掉一个点。
诶嘿
最小距离
题意:
\(n\)个点,\(m\)条无向边,每条边都带边权,此外还有\(p\)个特殊点,对于每个特殊点,求出它到离它最近的其他特殊点的距离。
解题思路:
暴力吧那就,骗分吧那就。
对于每个特殊点,我们将其\(dis\)初始化为\(0\),并全部放入优先队列跑\(dijkstra\),这时候记录一下哪个点是由它拓展的。对于每条连接不同拓展域的边,我们计算\(dis[x]+dis[y]+w\),并更新特殊点的答案。
水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水
即使说该点被重复覆盖,它到其拓展域中心的节点的距离也一定是对的,而且显然不可能绕另外一个拓展域去更新答案,上述做法正确。

浙公网安备 33010602011771号