【题解】Solution Set - NOIP2024集训Day44-45 图论
【题解】Solution Set - NOIP2024集训Day44-45 图论
https://www.becoder.com.cn/contest/5579
「BZOJ3706」反色刷
倒过来想,因为你不管怎么反色,形成的一定是若干个黑圈,所以答案就是黑圈个数(?
8min
我靠,不会求这个东西。😥
哦!看是不是一个环,重要的不是判边数=点数,而是每个点度数为 \(2\)。
https://www.becoder.com.cn/submission/2621783
答案大了?
哦!不是黑圈个数,其实就是连通块个数,因为在同一个联通快里面的黑圈是可以一次性走完的。
判无解的话,可以直接维护度数是奇数的个数。
有解的话,就是包含黑边的连通块个数。
同样维护每个连通块内黑边的个数,就行了。
「联合省选 2020 B」丁香之路
一股贪心的味道。
根据 \(s,t\) 把所有的边分成 \(6\) 部分:
- \(s\) 左边的;
- \(s,t\) 中间的;
- \(t\) 右边的;
- 跨过 \(s\) 的;
- 跨过 \(t\) 的;
- 同时跨过 \(s,t\) 的。
https://www.luogu.com.cn/article/wbf3o0j9(下面按自己理解重新把题解梳理了一下
直接做还是不太好像的,还是得建图。
我们先把这 \(m\) 条边放在图上,然后加入尽量少的边使从 \(s\to i\) 变成欧拉路。
连边 \((i,s)\),就是要变成欧拉回路,也即让每个点的度数都为偶数。
(注意:因为我们的加边是可以加重边的,所有这里的欧拉回路并不是严格意义上的。
下面会分成两步:
-
保证度数均为偶数
我们先把所有的度数为奇数的点拿出来,设为 \(a_1,a_2,\dots,a_n\),可以证明的是 \(n\) 是偶数,因为我们的奇数点一定是成对出现的。
然后我们贪心地将 \((a_1,a_2)\dots(a_{n-1},a_n)\) 连边,这样就保证了是一个不连通的但是度数是偶数的图。
这个贪心是对的,是因为变为为 \(|i-j|\)。
-
保证图联通
介于边权为 \(|i-j|\)。
我们把先排除无用的点,然后相邻两个点两两连边,这样一定不劣。
然后对使图联通的代价就是 mst 的两倍(因为一个连通块内的点的个数一定大于 \(1\),我们又需要保证度数仍都是偶数,就必须每条树边都加两条进去。
(题解感觉都没把实现过程写清楚,纠结了半天还是决定看一下代码,才理解。😥
「AHOI/JSOI2014」骑士游戏
做过。
显然 dp,所有的转移都是取 \(\min\),直接用最短路来转移,避免环就行了。
3min
「APIO2015」雅加达的摩天楼
做过。
先建图。其实就是求一个边权为 \(1\) 的最短路。(bfs
感觉像根号分治。
- \(p>\sqrt n\),直接暴力连边,至多 \(n\sqrt n\) 条。
- \(p<\sqrt n\),可以让 \(b\) 对 \(p\) 取模。然后这样的 \((b,p)\) 对之多有 \(n\) 个,暴力连边也才 \(O(n^2)\),调调参说不定就过了(
8min
???
好像这个做法就是对的???
好吧,是我算错了。/kk
- \(p<\sqrt n\) 的时候,实际上边数也只有 \(n\sqrt n\)。因为对于一个 \((b,p)\),最多连边 \(\dfrac np\),而对于同样的 \(p\),在 \(b\) 对 \(p\) 取模后,不同的 \((b,p)\) 只有 \(p\) 个,最多也就只有 \(n\) 个了。
所以总的时间复杂度就是 \(O(n\sqrt n)\)。
「JOI 2020 Final」奥运公交 (Olympic Bus)
做过。
显然跑一个 floyd,然后枚举反转的边就行了。
注意讨论一下枚举的反转边是不是在之前的最短路上,如果是的话,还需要重新跑一边 \(O(n^2)\) 的 dijkstra。因为这样的边至多只有 \(n\) 条,所以时间复杂度没问题。
「NOIP2017」逛公园
做过。(但是远古(两年前欸。
注意到 \(K\) 非常的小,所以,先跑一遍最短路,跑一下 dp。
\(f_{i,j}\):到 \(i\) 比最短路多用 \(j\) 的长度的方案数。
有转移:
「GXOI/GZOI2019」旅行者
(FAKE
啊?这不是一眼题?
直接把给定的 \(k\) 个点,先一起放在优先队列里面,然后跑 dijkstra
2min
https://www.luogu.com.cn/record/180232097
虽然但是,她 WA 了,因为可能出现自己回到自己的情况。
我们直接在最短路里面记录一下最短和次短,以及起点,回到自己的情况,就用次短来更新就行了。
2min
https://www.luogu.com.cn/record/180246286
然而还是挂了,因为这个次短和最短可能来自同一个起点,这样就没办法转移了。
实际上,直接正反分别跑一边 dijkstra,然后枚举一条边 \((u,v,w)\)。
答案就是:\(\min(dis_{0,u}+w+dis_{1,v})\)。
注意判一下 \(u,v\) 是不是同一起点,如果是的话就直接跳过。可以证明最终的答案哪条路径一定是会被上面的一条边所统计到的。
https://www.luogu.com.cn/article/nagswult
官解给了一个 trick:
同样还是处理起点和重点相同的情况。
(具体怎么做,可能参照上面的题解。这里解释一下为什么。
两个数不同的充要条件是:这两个数的二进制中存在一位是不同的。
于是,每一位考虑一定可以考虑到每一对不同的数。
「COCI2017-2018#3」portal
做过。
印象还挺深的。
有一个结论:
-
对于所有 必要 的瞬移方式,一定存在一个位置,使得这个位置可以同时开启这两扇门。
Why?
考虑反证。如果存在一个 必要 的瞬移方式,不存在这样的位置。
那么就是说一定有一个障碍物在她们中间,既然有了这个障碍物那么为何不直接在这个障碍物上面生成一扇门呢?还要绕过障碍物去开另一扇门。
有了这个结论,我们在最短路转移的时候就分成两种:
- 正常走;
- 枚举两扇门相对当前的方向,然后转移。
13min(还好回忆起来了。😅
「JOISC 2020 Day4」治疗计划 (Treatment Project)
wtf,一点思路没有。
嗯?最短路(瞄到标签。
「HNOI2009」最小圈
做过的分数规划板子。
直接二分答案,然后对每一条边 \(-mid\),如果图上存在负环,说明答案可以更大。
但是好像 spfa 判负环是可以被卡成指数的。😅(回头研究下。
https://www.cnblogs.com/luckyblock/p/14317096.html
「SCOI2011」糖果
做过的差分约束板子。
我们要从超级源点连向每一个点,那么一定是要让 \(dis_i<dis_0\),但是又要保证所有的 \(dis\) 都是正的,那我们不妨先钦定所有的 \(dis\) 取相反数,然后就行了。
关于 spfa,她死了。所以我们来想想 缩点 + topo 吧。
emmmm,也挺显然的。
如果一个 scc 内部的权值和不是 \(0\),那么一定无解。于是缩点,然后 topo 跑最长路就行了。
注意最短路/最长路和题目要求最少/最多没有关系,而是跟边权有关系。
「CF1521D」Nastia Plays with a Tree
做过。(而且很近,就在一个月前,记得当时是自己做的,还做了蛮久。
哦!记起来了,是一个挺 ex 的树形 dp。
(看不懂以前的代码了。😅
其实就是要剖成尽量少的链,然后在首尾拼接起来。
\(f_{i,0}\):\(i\) 这棵子树,\(i\) 只向下选择了一条边,最小移动的边数。
\(f_{i,1}\):\(i\) 这棵子树,\(i\) 向下选择了两条边,最小移动的边数。
「ARC121E」Directed Tree
题看错了……
「边的方向由父亲连向儿子」
nb!所以题目的意思应该是:\(a_i\) 可以是除了 \(i\) 的祖先以外的点。
考虑二项式反演。
\(f_{i,j}\):子树 \(i\) 内,钦定有 \(j\) 个不合法的方案数。
那么:
-
如果 \(u\) 是合法的。
(FAKE
\[f_{u,i}=\left(\sum f_{u,i-j}\cdot f_{v,j}\right)\times i \] -
如果 \(u\) 是不合法的。
嘶,这个不好转移啊。
21min
https://www.luogu.com.cn/article/172v0emu
实际上,没有必要按照 \(u\) 是否合法来划分子问题。
(因为,问题也是很明显的,那就是在只考虑 \(u\) 的子树的时候,\(u\) 一定合法啊喂,所以我们就只用考虑 \(u\) 合法的情况。
(而我那个 \(u\) 合法的转移,也是错的。
其实,我们可以按照 \(u\) 是否跟子树中的元素交换来划分子问题。
-
如果不交换。
\[f_{u,i}=\sum f_{u,i-j}\cdot f_{v,j} \] -
如果交换。
可以先把 \(u\) 算完了然后再统一算。
(还是比较有启发性的转移方式的。
\[f_{u,i}\gets f_{u,i}+f_{u,i-1}\times ((siz_u-1)-(i-1)) \]
「ARC121F」Logical Operations on Tree
考虑树形 dp。
\(f_{u,i}\):子树 \(u\) 合并完剩下的值为 \(i\)。
转移的时候问题在于,合并的这条边什么时候被合并。
合并的话,相当于我们在某一时刻,有一次机会可能让两棵子树的根节点中的一个变化。
思考一下合并数值时的一下性质。
- 两个数值相同,则合并无影响;
- 不同的话。
- \(\text{AND}\) 让 \(1\to 0\)。
- \(\text{OR}\) 让 \(0\to 1\)。
所以我们考虑重新定义状态:
\(f_{u,i,j}\):子树 \(u\) 合并完剩下的值为 \(i\),中途可否剩下另一个值(\(j\))。
嘶,仍然不好转移,因为合并后两棵子树不再独立,我们还要考虑合并之后的过程。
27min
https://www.luogu.com.cn/article/e2qz2q2i
面这个计数不好做,「套路地先考虑如何判断一个方案是否合法」,试图来寻找合法的充要条件来转换题意。