优化建图技巧

常见优化建图技巧 习题 题解。

已完成[8/11] 题解[8/11]

1.P5025 [SNOI2017]炸弹(紫)

容易想到每个炸弹向它爆炸范围内的炸弹连边,跑多源搜索,能抵达的节点数量即是答案。

考虑线段树建边优化,线段树内父亲向儿子连边,炸弹向范围区间连边,边数 O(nlog⁡n)\mathcal O(n \log n) 条。

然后 tarjan 缩点成 DAG,跑搜索记录能到达的最左右端点即可。

时间复杂度 O(nlog⁡n)\mathcal O(n \log n)。

CODE

2.P3588 [POI2015] PUS(紫)

貌似是差分约束。

区间向区间连边,线段树优化建边,建虚点。

具体地,按套路建儿子向父亲连边的线段树,把操作区间分割的最多 k+1k+1 个子区间向虚点连边,虚点向给的 kk 个点连边,边数 O(klog⁡n)\mathcal O(k\log n)。

接着拓扑跑最长路即可。

对于确定的数,即 dis⁡\operatorname{dis} 已确定。

时间复杂度 O(nlog⁡n)\mathcal O(n\log n)。

CODE

3.P5471 [NOI2019] 弹跳(紫)

相当于例题加强成二维矩阵。

考虑树套树优化建图,外层线段树,内层动态开点线段树,空间复杂度 O(nlog⁡2n)\mathcal O(n\log^2 n),边数 O(mlog⁡2n)\mathcal O(m\log^2n),无法通过。

优化 11:树套树内层换成 set 空间复杂度 O(nlog⁡n)\mathcal O(n\log n)。

优化 22:不直接连边,每次从树套树里取出扩展即可,

优化 33:由于 dij 上每个节点只会被删除和扩展一次,所以取出扩展完删除即可。

时间复杂度 O(nlog⁡2n)\mathcal O(n\log^2n),空间复杂度 O(nlog⁡n)\mathcal O(n\log n)。

4.P5331 [SNOI2019]通信(黑)

网络流模型:

s→xis \to x_i,容量为 11,费用为 00。

xi→Tx_i \to T,容量为 11,费用为 ww。

xi→xj′(i>j)x_i\to x_j'(i>j),容量为 11,费用为 ∣ai−aj∣|a_i-a_j|。

xi′→Tx_i'\to T,容量为 11,费用为 00。

跑最小费用最大流即可,边数 O(n2)\mathcal O(n^2)。

考虑优化,由于限制 i<ji<j 且费用带有绝对值。

考虑 cdq 分治,每次右区间向左区间连边。

首先将区间内权值排序去重,连成一条链,费用为相邻两点之差,将其作为连接左右区间的虚点。

具体地,区间点向虚点连边时,向权值对应链上的位置连边即可,这样就通过累积权值之间的差值实现了费用的绝对值(yytj。

CODE

5.P6378 [PA2010] Riddle(紫)

点的状态必然是选或不选,考虑 2-SAT。

记 xx 表示选,x′x' 表示不选。

对于边的限制,至少一点选,直接 x′→yx'\to y,y′→xy'\to x,表示不选 xx 必选 yy,不选 yy 必选 xx。

对于部分的限制,一个点向该部分中除它以外的所有点连边,直接连边数是 O(n2)\mathcal O(n^2) 的。

考虑前缀优化建图。

记 preipre_i 表示前 ii 个点有关键点,prei′pre_i' 表示前 ii 个点没有关键点。

部分内连边:

ai→preia_i\to pre_i,prei′→ai′pre_i'\to a_i',表示选 aia_i 前 ii 个就有关键点。

prei−1→preipre_{i-1}\to pre_i,prei′→prei−1′pre_i'\to pre_{i-1}',表示前 i−1i-1 个点有关键点那么前 ii 个点有关键点。

prei−1→ai′pre_{i-1}\to a_i',ai→prei−1′a_i \to pre_{i-1}',表示前 i−1i-1 个点有关键点那么 aia_i 不选。

时间复杂度 O(n)\mathcal O(n)。

CODE

6.CF1215F Radio Stations(2700)

2-SAT。

先看限制一,u,vu,v 至少有一个,连边 u′→v,v′→uu'\to v,v'\to u 即可。

限制二,u,vu,v 最多有一个,连边 u→v′,v→u′u\to v',v\to u' 即可。

限制三,选择的点的区间有交集,记任意一点 ff,考虑前缀优化建图,记 preipre_i 表示 f≤if\leq i,prei′pre_i' 表示 f>if>i。

连边:

i→preli−1’i\to pre_{l_i-1}’,i→prerii\to pre_{r_i}。

preli−1→i′pre_{l_i-1}\to i'。

preri’→i′pre_{r_i}’\to i'。

prei→prei+1pre_i \to pre_{i+1}。

prei+1’→prei′pre_{i+1}’\to pre_i'。

最后建图跑 tarjan 即可,时间复杂度 O(n)\mathcal O(n)。

CODE

7.CF1007D Ants(3200)

2-SAT。

考虑如何确定限制,树剖线段树反向记录每条路径对应在线段树上的点,即记录每条边被哪些路径包含,线段树上的叶子节点即为边。

对于一条树边,其被包含的路径编号即为它在线段树上的祖先和它的路径编号并集。

如果选一条路径上,那么它在线段树上的点的祖先和儿子的路径都不能选,即线段树上根到叶子的一条路径上的点的路径编号最多选一个。

考虑线段树上根前缀优化建图,套路了不讲。

时间复杂度 O(nlog⁡2n)\mathcal O(n\log^2 n)。

CODE

8.P7712 [Ynoi2077] hlcpq(黑)

有暴力,O(n2)\mathcal O(n ^ 2) 建边,tarjan 求割点。

再考虑优化,拿出线段树优化建边过程,考虑到区间限制,扫描线加主席树即可。

然后发现,建虚点会使答案不对,故只构造结构而不建边。

回顾 tarjan 求割点的过程,树边递归完后执行 lowy→lowxlow_y\to low_x;返租边执行 dfny→lowxdfn_y\to low_x。

对于树边,每次在线段树上找没有更新 dfndfn 的节点,然后更新 lowlow 即可。

对于返租边,求出边的 dfndfn 最小值即可。

时间复杂度均摊 O(nlog⁡n)\mathcal O(n \log n)。

CODE

posted @ 2022-07-01 11:40  蒟蒻orz  阅读(53)  评论(0)    收藏  举报  来源