唐山一中暑假集训 III
Day 12
欧拉图 二分图
- P10939 骑士放置。
比较经典。
我们注意到对于原图的 \(i + j\) 的奇偶性进行染色,注意到这样的情况一定是合法的。
我们每次考虑对于走“日”字的格子,每一次都进行连边,然后进行二分图最大匹配即可。
复杂度略高,但是这肯定是跑不满的。
实测:复杂度是 \(O(n^3m^3)\) 的做法最慢一个点跑了 131ms,快的飞起。
- P3033 [USACO11NOV] Cow Steeplechase G。
很优美的性质。
我们知道二分图的最小点覆盖=最大匹配=点数-最大独立集。
然后我们把所有相交的线段连起来,然后计算二分图点覆盖,也就是求出这个二分图的最大匹配即可。
强连通分量 双连通分量
-
P2921 [USACO08DEC] Trick or Treat on the Farm G。
我们考虑当然先进行 tarjan 缩点。如果这个点所在的 scc 的大小 \(\ne 1\),那么说明这个一定在环上,直接找出环即可;如果这个 scc 的大小 \(= 1\),说明这个点一定不在环上,我们接着走他的 \(nxt_i\) 一直走直到我们找到了位于环上的点即可。
复杂度 \(O(n + m)\)。 -
P5022 [NOIP 2018 提高组] 旅行。
先考虑 \(m = n - 1\) 的情况。很明显,我们从 \(1\) 开始 DFS 即可,每次我们寻找编号最小的点去走即可。
再考虑 \(m = n\) 的情况。我们充分发扬人类智慧,每次枚举环上的一条边,考虑断掉环上这条边,然后再重复 \(m = n - 1\) 的做法即可。
所以,我们进一步简化一下这个东西,我们直接去枚举每一条边,然后再考虑 DFS。如果断掉的这个不是环上的边,那么最后的路径长度一定 \(< n\),我们直接舍掉即可。
Day 13
Tarjan
-
P4782 【模板】2-SAT。
我们考虑拆点计算。假设我们把 \(u\) 拆成 \(u\) 和 \(u + n\),分别表示权值是 \(0\) 和权值是 \(1\) 的点。
我们钦定第一个不满足条件,则第二个必须成立;同理第二个不满足条件,第一个必须成立,我们考虑这样连边。
然后我们进行 Tarjan 缩点,每次做出来的 SCC 我们考虑如果 \(u\) 和 \(u + n\) 是否属于同一个 SCC 即可。 -
P3225 [HNOI2012] 矿场搭建。
我们先考虑通过 Tarjan 跑出所有的割点。然后我们考虑使用 DFS,每次我们遍历一个联通块,我们假设这里面没有割点,那很不幸,我们只能建立两个点作为出口,方案可能性是 \(\binom{siz}{2}\);如果有一个割点,我们直接再建立一个点作为出口即可。方案数是 \(siz\);如果有大于等于两个割点,我们就不需要再建立任何出口了。 -
P3513 [POI 2011] KON-Conspiracy。
我只能说,这题很人类智慧了。
我们先考虑如果这两个点之间存在连边,如果 \(u\) 不在团中,那么 \(v\) 一定会在团中;如果 \(v\) 不在团中,那么 \(u\) 一定会在团中。所以,我们考虑使用 2-SAT 找到一组可行的合法解。
然后,我们充分发扬人类智慧,注意到团和独立集存在天壤之别,所以我们根据数学直觉,会发现每次只有可能独立集或者团中的一个点到另外一边去,或者直接交换其中的两个点即可。 -
P12954 [GCJ Farewell Round #2] Railroad Maintenance。
挺神的一道题。
我们考虑把每一个铁路线定义为一个点,这样我们如果删掉这个点那么就会多出一个连通分量,很明显这就是一个割点。
所以我们考虑转化成求解割点即可。 -
P2403 [SDOI2010] 所驼门王的宝藏。
我们考虑如何合理建图。首先,我们把每一行的点和每一列的点给抽象下来,也就是说额外新开 \(R + C\) 个点。也就是,我们钦定 \([1, R]\) 之间表示每一行,\([R + 1, R + C]\) 表示每一列,\([R + C + 1, R + C + N]\) 表示每一个点。
我们按照操作进行连边,最后再对于每一行的点向这一行的所有点连边,每一列的点向这一列连有向边,然后我们进行 Tarjan 缩点,然后我们再考虑拓扑 DP 即可。
Day 14
最大流 最小割 费用流
-
P1345 [USACO5.4] 奶牛的电信 Telecowmunication。
很明显,我们注意到这其实要求的是最小割,但是我们发现一个问题,最小割是割掉的边,这里我们要割掉一个点!
所以,我们把每一个不是源点和汇点的点考虑分裂成两个,分别命名为 \(u\) 和 \(u + n\),割掉这个点相当于割掉 \((u, u + n)\) 这条边,所以我们在这里连一条流量是 \(1\) 的边即可。
然后计算最小割,也就是最大流即可。 -
P2472 [SCOI2007] 蜥蜴。
考虑拆点,我们把每一个点拆成一个入点、一个出点,然后考虑建立 \((u, u + n \times m)\),流限制是 \(h_u\)。然后我们考虑建立超级源点和超级汇点,超级源点向每个蜥蜴连一条长度为 \(1\) 的边,每一个出口向汇点连一个长度是无穷大的边,然后我们再考虑从一个点能够跳到另一个点的长度还是正无穷的边即可。
最后计算最大流即可。 -
P4174 [NOI2006] 最大获利。
这个东西貌似叫什么最大权闭合子图?
我们考虑把 \(s\) 向每一个用户连一条价值为用户的边,然后把每个用户向每一个所需要的设备连边,边权是无穷大;最后我们把设备向汇点连边,边权是这个设备的价值。
然后我们考虑原图的最小割,因为是最小割所以我们一定不回去割掉边权为无穷大的边,因为这样并不优;所以不论我们会割掉边权是什么的边,我们都存在一个合法的含义去解释,然后我们计算一下所有用户的价值之和,然后减掉最小割即可。
Day 16
-
P3435 [POI 2006] OKR-Periods of Words。
很适合加深对于 KMP 的理解!
我们发现,这个东西本质上就是在求最短公共前后缀,和 KMP 有异曲同工之妙。我们发现,根据 border 数组的定义,我们从位置 \(i\) 出发,每一次走 \(nxt_i\),如果这个位置还不是 \(0\),说明还存在公共前后缀,就可以一直走;否则我们停下来即可。
接着,我们自信一交(学的 yaoxi),会发现 TLE 了!考虑一下优化。因为我们每一次都在跳 \(nxt\) 数组,这个复杂度理论上可以达到 \(O(n)\),所以总的时间复杂度其实是 \(O(n^2)\) 的。所以我们每一次计算完 \(i\) 之后直接修改 \(i\) 的 border 值,这样每一次从后面的跳到 \(i\) 的时候可以直接向前。相当于记忆化一下。 -
P2375 [NOI2014] 动物园。
考虑到 \(num\) 数组其实和 \(nxt\) 数组的含义还是很类似的,我们考虑先进行 KMP 然后再计算。我们记录 \(nxt_i > \frac{i}{2}\),那么这一定不是 \(num\) 数组。我们考虑每一次走 \(nxt_i\),每一次都往前跳,知道满足 \(nxt_i < \frac{i}{2}\) 即可。最后统计答案即可。 -
P4391 [BalticOI 2009] Radio Transmission 无线传输 & SP263 PERIOD - Period。
这两道题对比着来看。
我们注意到最长周期其实就是 \(n - nxt_n\),所以第一个题我们就切了。
然后我们来看第二个题,因为每一个前缀我们要求必须是正好的,所以我们求出的最长周期 \(i - nxt_i\) 必须得是 \(n\) 的因数,然后一个一个判断即可。 -
P4824 [USACO15FEB] Censoring S。
我们考虑 KMP,但是我们要求的是删除掉所有的形如 \(t\) 的串串。所以我们维护一个栈,同时考虑 KMP 的时候,如果 \(j = m\) 的时候,我们就考虑吧栈顶的 \(m\) 个元素弹出去,然后我们令 \(j = nxt_{top}\)。
然后我们就输出栈中的每一个元素即可。
浙公网安备 33010602011771号