专题:图论1
专题:图论 1
悲喜交加。
A. [arc084_b] Small Multiple
同余最短路板子,注意到每加入一个数其实就是让 \(x\) 变成 \(10x+c\)。
B. [abc216_g] 01Sequence
又是板子,这是差分约束板子。
差分约束就是形如 \(x_i-x_j\le c\) 的东西。
因为 \(dis_i\le dis_j+c\)
所以可以看做是从 \(j\) 向 \(i\) 连一条边来限制 \(dis_i\) 的大小。
这个题设 \(dis_i\) 表示前缀 1 的个数,发现 \(0 \le dis_{i+1}-dis_i\le 1\)。
\(dis_r-dis_{l-1} \ge c\) 这个同时取负号就行。
但是这个出题人恶毒的卡了 SPFA,所以可以设 0 的个数,这样就只有正边权了。
C. [luogu P2662] [WC2002]牛场围栏
神人题目。
解法一:
首先注意到一件事情,这个背包的上界肯定不大,所以可以尝试证明一下上界。
因为所以的表示都可以变为形如 \(a(r-m)\) 和 \(ar\)。
所以当左右有交时后边全部可以表示出来,就是:
所以发现 \(ar\) 大致是 \(\frac{r^2}{m}\) 的。
直接跑 \(n\) 遍 + \(O(m)\) 转移的完全背包做到 \(O(nm^2)\)
解法二:
发现其实可以钦定一个数作为剩余系的模数。
然后就变成了同余最短路。
设 \(dis_i\) 表示到 \(i\) 最短跑几轮(几个周期)。
这样 \(dis_i+cx\)(\(c \ge 0\))都能表示。
那么 \(dis_i-x\) 就表示不了了,将所有 \(dis_i-x\) 取 \(max\) 即可。
复杂度 \(O(m^2\log m)\)
D. [luogu P2680] [NOIP 2015 提高组]运输计划
神秘题目。
首先发现答案一定是在最长的询问上。
所以更改只可能更改这个上面的边。
修改一条边可以看做是所有经过这条边的询问减去这个边权,和不经过这条边的长度取 \(max\)。
前者已经知道是当前的最长询问。
后者可以直接树剖得到。
首先边权拍点权,然后发现不经过其实就是将所有经过的区间除去后的所有区间,直接树剖时记录一下 \([dfn[top[x]],dfn[x]]\) 即可。
E. [luogu P4211] [LNOI2014]LCA
咕咕咕。
F. [luogu P1852] 跳跳棋
神人题目!
首先发现题干给出了不能越过两个棋子跳跃,这就限制了许多情况,现在就只能中间向两边跳,或左右其中一个向中间跳。
发现这是一棵树。
显然不能直接建树。
由于有很多重复的状态,所以可以类比 SAM 进行一种压缩。
当 \(x,y,z\) 的区间包含 \(a,b,c\) 时,可以讲操作等价于对 \(x,y,z\) 进行缩区间的操作,因为此时 \(a,b,c\) 是 \(x,y,z\) 的祖先。
那么这个缩小的过程怎么操作呢?
假设目前有 \(b-a\le c-b\)。
此时只能将 \(a\) 向中间缩,而应该缩小多少呢?
发现如果 \((a-x)\equiv 0 \mod (c-b)\)。
那么可以直接跳到 \(x\)。
否则,则说明当前可以跳 \(b-a\le c-b\) 的祖先不存在二者的 \(lca\)。
直接狂跳不止就行。
跳不动就似了。
复杂度不会(
G. [CF 1005F] Berland and the Shortest Paths
水题。
发现求 \(\sum dis_i\) 最小,首选最短路树,这样每个根链前缀和都是 \(dis_i\)。
那么考虑加入一条返祖边。
肯定会造成环,那么就要在最短路树上割边,并保证不会改变最短路。
设 \(u,v\) 为两端点,\(w\) 为边权。
则一定是当 \(dis_v=dis_u+w\) 时才行。
并且只能断掉 \((v,f_v)\) 这条边。
因为断其他边一定导致其他 \(dis_{f_v}\) 变大。
所以直接判断,记录所有断连可能,暴力搜就行。
H. [CF 507E] Breaking Good
大水题。
发现首先是求最短路。
然后要求改变的道路数量最小。
那么当经过的 1 越多时,修建的越少,炸毁的也越少,所以直接以边权作为第二关键字跑最短路就行。
太水了?
I. [CF 1981E] Turtle and Intersected Segments
困难题。
发现如果存在 \(a_i\le a_j\le a_k\) 并且两两连边,则一定不会连 \((i,k)\),因为连 \((i,j)\) 和 \((j,k)\) 更优。
那么现在钦定只让 \(i\) 连所有 \(l_j\le l_i\) 的线段。
如果它们交与这个线段,则一定经过了 \(l_i\),那么这些线段就有交。
所以只需要连接 \(a_i\) 的前驱后继即可。
然后每次扫到左端点就加入,右端点就删除。
J. [agc004_d] Teleporter
简单题。
发现 1 一定是要变的(读者自证不难)。
那么求的就变成了将所有的点到 1 的距离变为小于等于 \(k\)。
直接自底向上 \(dfs\),如果深度特别大,就直接将这颗子树连在 1 上。
这样处理完一定是最优的。
K. [agc016_d] XOR Replace
有趣题。
发现题目其实就是在吓唬人。
假设当前位是 \(x\),下一个操作的位是 \(y\),当前异或和为 \(s\)。
那么当前位变为 \(s\)。
下一次操作使得 \(y\) 变为 \(x\oplus s\oplus s\) 也就是 \(x\)。
如果再往下就会发现其实就是将下一个操作位变为上一个操作位的数。
那么此时就有点头绪了,如果可以一直这么交换,则答案就是所有 \(a_i\neq b_i\)。
但事实真的如此吗?
如果我们无法通过一次跳跃到达另一个连通块,则一定会花费 1 来进行一个值的替换(比如样例 4 中的 \([1,2],[3,4]\))。
首先一个连通块内的 \(a_i\),\(b_i\) 数量一定是相同的或者差 1。
又发现,如果一个 \(a_i\) 连向了 \(b_i\),那么一定可以找到一个 \(a_j,b_j\) 其中的 \(b_j=a_i\),此时不需要额外的代价。
所以只需要将 \(a_i\) 向 \(b_i\) 连边,然后求连通块。
如果求出新的连通块,则答案一定需要接受这联通块的代价。
不过孤立点需要跳过。
最后因为首个 \(s\) 是新加入的,可以除去一个连通块的代价(如果 \(s\) 不是孤立点)。
L. [CF125E] MST Company
恶心题。
发现这是一个最小生成树。
但是限制了 1 号点必须要有 \(k\) 度。
首先肯定先将 1 删除后进行操作,先建出最小生成森林。
考虑将 1 连入,肯定先将图联通,正常联通后再考虑怎么加入剩下的边。
剩下的边加入都会产生一个环,所以使用消圈。
具体每次找到环上最大的边,然后删除。
每次找到这个操作产生代价最小的边加入即可。
怎么找最大的边呢?
其实就是根链最大值(意会一下)。
然后每次操作就完了。
M. [CF1707C] DFS Trees
简单题。
发现边权两两不同,所以可以得知最小生成树是唯一的。
那么先建出最小生成树,考虑每次 dfs 会发生什么。
肯定只考虑返祖边对答案的影响。
如果在一次 dfs 中一个返祖边的 \(u,v\) 不是祖父关系,那么一定会出现 \(u,v\) 中的一个被遍历到的时候另一个没被遍历到,那么这条边就会被经过,则最小生成树被破坏。
那么只有 \(u,v\) 为祖父关系时才可能是对的。
此时假设 \(dep_u\le dep_v\),那么如果 \(u\) 向 \(v\) 的树上边比这条边大,那么一定会经过这条边,则最小生成树被破坏。
那么这样只需要对每个返祖边进行这个讨论即可。
但是如果 \(u,v\) 本就是祖父关系,那么在除了包含 \(v\) 的子树其他都是合法的,这时可以使用差分。
一个根合法就是对于所有返祖边这个点为根都合法。