CF576D - Flights for Regular Customers 题解

开始挖 tzc 遗产(?

这好像是上个赛季的一个 jxd 作业。


首先直接 BFS 肯定是不行的,因为你会一边走边会一边增加,那就要加一维步数,那肯定吃不消的。

显然,边集只有 \(\mathrm O(m)\) 种,而且对应着若干个连续的时间段。我们不妨枚举最优答案的最后一步是在哪个时间段里面。然后对于每个时间段,它的边集显然是固定的了,那么就可以直接 BFS 了。

那么现在瓶颈在于,该时间段左端点的时候哪些点是可以从 \(1\) 出发走到的,这个怎么求,求出来就 BFS 就行了。

这个就是比较套路的东西了。某些萌新可能迷惑邻接矩阵到底有什么用,它明明能被邻接表代替。它终究是一个矩阵,满足这样一个性质:两个邻接矩阵相乘,所得积的 \((i,j)\) 表示若先走前者代表的边集,后走后者代表的边集,那么 \(i\to j\) 的路径数。这也太容易理解了,就是矩乘的定义。然后如果用 bool 型存的话就表示可达性,它相当于是一个广义矩乘,也是满足性质的。

那么每个时间段的初始点集就是之前的若干个邻接矩阵相乘看第一行就可以了。这个可以从前往后扫的过程中一路乘,对于每个时间段乘快速幂。那复杂度就是 \(\mathrm O\!\left(n^3m\log\right)\),过不去。然后是另一个 trick:矩阵里都是 bool,于是可以搞出乘法中前者的行和后者的列的 bitset,然后查询的话复杂度就除以了一个 \(w\)。

code

上一篇:R删除数据列基于dplyr包


下一篇:[R]在dplyr基础上编写函数-(1)eval