提高组图论专题 2 做题记录
提高组图论专题 2 做题记录
^A [NOIP2013 提高组] 华容道
显然想要将目标棋子挪到目标位置,肯定是依靠空白格子来移。也就是说,空白格子始终会在目标棋子四周来帮助目标棋子移动。所以我们设的状态是 \((x,y,k)\) 表示当前目标棋子在 \((x,y)\),空白格子在它的哪个方位。
转移有两种:\((x,y,k)\to (x,y,k')\)(移动空白格子) 和 \((x,y,k)\to(x',y',k')\)(交换空白和目标棋子)。前一种 BFS 得到边权,后一种边权直接为 \(1\)。对于每一个询问,先将空白格子移到目标格子旁边,然后按照上面的连边跑最短路即可。
B [雅礼国庆 2017 Day6] Star Way To Heaven
首先有显然做法:二分最小距离,然后暴力并查集连边,判断上边界和下边界是否在一个连通块内即可。理论上只能拿到 \(80\) 分,但是随便卡卡常就能直接艹过去。
考虑正解。考虑到我们的目标就是让上下边界被割开,那么假如我们将这些割开区间的圆心从上到下顺次连边,它们一定是所有圆心构成的完全图中最小的边。这启发我们利用最小生成树求解,因为最小生成树既可以保证选的边离圆心最近,也可以保证本身就是最小的边。当我们跑到上下边界相连的时候即可停止,此时求出所有已连边的最大值,除以 \(2\) 即为答案。
由于图是完全图,因此用不带堆优化的 Prim 算法即可 \(O(k^2)\) 通过。
C [CF1005F] Berland and the Shortest Paths
显然考虑最短路树。对于每一个点,求出它在最短路树上可能的前驱,然后暴力 dfs 去看选哪些前驱,也就得出了选哪些边。
注意此题用链式前向星会 MLE,因此应当使用邻接表,或者用栈手写递归。
*D [JOI 2017 Final] 足球
图论建模题,和网络流的感觉有些像。考虑只去关注足球的状态,那么它有两种:在球员脚下或在空中飞行。而后一种又分为两种:横向飞行或纵向飞行。那么为了在模型中描述这三种状态,我们就需要用到经典技巧:拆点。
接下来连边。按照题目所说的将相邻格子的对应点连起来。值得注意的只有一种情况:由飞行状态改为在球员脚下状态。此时需要有一个球员跑到这个格子并控住这个球,因此我们还需要求出离这个格子最近的球员。BFS 一边即可。
最后直接跑最短路即可。我们不必关注其他情况,也不必关注重边,因为它们一定不会比正确答案优。
E [CF1981E] Turtle and Intersected Segments
最近模拟赛做这种生成树的题还比较多。考虑什么样的边一定不优,假如三条线段两两相交,那么我们只需要按照 \(a\) 的大小顺次相连即可,而最小的和最大的连一定不优。于是我们就可以得到这样的结论:
- 每一条线段只需要和与它相交且差的绝对值最小的线段连边即可。
差的绝对值最小其实就是求前驱后继,而统计相交时我们可以只统计右端点在这条线段上的线段。容易想到的是直接上树套树暴力解决,但是有更简单的方式。考虑离散化后扫描线,单次插入或删除一条线段,并用 set
维护当前在扫描线上的线段 \(a\) 的值。插入一条线段时用 set
求前驱后继即可。最后暴力跑一边 Kruskal 即可得出答案。
^F [JOISC 2017 Day2] 火车旅行
发现这道题是在序列上走,求最优解的问题。那么可以考虑倍增求解。
设 \(l(i,j)\) 表示从 \(i\) 出发走 \(2^j\) 能达到的最左的位置,\(r(i,j)\) 同理。注意到题目中允许走回头路,因此转移的时候需要从两端都进行转移。以 \(l(i,j)\) 为例:
接下来问题就是怎么统计答案。考虑从较左的点开始扩展区间,直到再扩展就会包含较右点。然后再扩展较右点,直到在扩展就会和刚才的区间有交。此时两个区间最后走的点中间一定不会再有停靠点了(否则一定还可以扩展),直接输出此时的答案即可。
*G [雅礼集训 2018 Day8] A
最小树形图模板题。
*H [JSOI2010] 满汉全席
2-SAT 模板题。将每一种材料分成汉式和满式两种,根据每一位评委的要求连边跑 SCC 即可。