首页 > 其他分享 >[做题笔记 #3] 图论

[做题笔记 #3] 图论

时间:2024-11-16 16:45:17浏览次数:1  
标签:图论 2024.11 16 短路 分治 笔记 贡献 做法

目录

[做题笔记 #3] 图论

[ ] 里的是不确定的。

1~11 是 2024 年国庆的题。

1. P6175 无向图的最小环问题

Floyd 求最小环板子。大概是在 Floyd 的过程中,在算当前中继点对最短路的贡献之前,处理它和编号更小的点形成的环(利用当前的最短路信息),这样最短路就不会包含枚举到的点形成的另外两条边,于是算环时不会出问题。

具体见代码。

2024.11.15

2. P4568 [JLOI2011] 飞行路线

分层图最短路。感觉可能很经典,但我之前没怎么做过分层图的题。

总结:特殊走几条边就把图分几 \(+ 1\) 层(可以往下走几层),层内的图就是原图的复制品,而层和层之间的边用于实现特殊移动。

2024.11.15

3. P5304 [GXOI/GZOI2019] 旅行者

二进制划分 + 最短路 做法

  • 每次看一个二进制位,把编号的这一位为 \(0\) 的作为起点,这一位为 \(1\) 的最为终点。建立超级源点连向所有起点,建立超级汇点由所有终点连向它。
    • 因为两个不同的非负整数都会有至少一个二进制位不同,所以任意一对点一定会在某一轮中一个是起点,另一个是终点。
    • 因为取 \(\min\),求 \(\min\) 的过程中可以重复,因此不用担心此做法带来的重复的问题。
  • 感觉这个做法很有启发性。它可以用来解决的问题有三个特征:
    • 要求出一批东西两两之间的贡献合到一起的结果。
    • 合到一起的过程中允许重复。
    • 每轮贡献的计算的时间复杂度 不受 要算贡献的点的个数 限制,而 [可能] 更大。
  • 这种做法的本质:
    • 考虑 CDQ 分治。CDQ 分治的划分类似于按二进制位划分,算左对右的贡献,但是它可以解决不允许重复的问题。但是这样的代价是每次要分治下去,即下面的每一层都是被割成一段段的,这些段互相之间不算贡献。
    • 但是如果每段(每次)算贡献的代价不被段的长度所限制,而可能更大(比如说和总点数有关),CDQ 的复杂度就会很大。
    • 这种做法其实是抓住了可重的特性,把 CDQ 分治中每一层的贡献一起算。这样就把时间复杂度削减下来了。
  • 这种做法的本质也说明了它的优势、它为什么不能被 CDQ 分治或二进制分组替代。
  • 我之前尝试过用此做法来算贡献的异或和,我试图通过规定位数 + 按位取反来使每对点间的贡献都算奇数次(偶数次的取反后就算奇数次,合到一起还是奇数),但哪些取反哪些不取又要划分,我还没想清楚。

正反建图 + 最短路 做法

正确性有点神秘。

对于每条边去求。注意判掉有端点不可达的情况、起点终点相同的情况(记 frm)。

关于正确性:水哥给我讲过,记不太清了,好像是答案的那条路径一定能找到一个分割的地方,还是说所有路径都可以?

2024.11.15

4. P6961 [NEERC2017] Journey from Petersburg to Moscow

感觉是神秘且很牛的题。

前 \(k\) 大,考虑枚举一条边作为第 \(k\) 大,复制一张原图作为新图,在新图上,把边权 \(\geq\) 它的边都减去它,把边权 \(<\) 它的边的边权都设为 \(0\),跑最短路,加上 \(k \times\) 它的边权 作为当前的值。分类讨论这条边与路径上第 \(k\) 大的边的大小关系,发现一定大于等于真正的答案。枚举到某条边,它就是第 \(k\) 大的边时,用它算出来的值就等于答案。但我们并不知道这条边是哪一条,于是求每一次的值的 \(\min\) 作为答案。但是还有一种情况,就是边不足 \(k\) 条时应该直接跑最短路。容易发现即使边 \(\geq k\) 条时,直接跑最短路也不会比答案更短,于是再和直接跑最短路的结果(原图的最短路)取 \(\min\) 即可。

具体见(%%%):[P6961 NEERC2017]Journey from Petersburg to Moscow - 洛谷专栏 (luogu.com.cn)

2024.11.15

5. P4899 [IOI2018] werewolf 狼人

用两棵 Kruskal 重构树维护编号 \(\leq\) 和 \(\geq\) 某个值时的连通性。每次查询尽量往上跳,直到跳不动,在两棵树上各得到一棵子树。要看两棵子树中是否有相同的点。

用 DFS 序转化,两棵子树的限制各作为一维,跑二维偏序即可。

Kruskal 重构树有两种构建方法:

  1. 按边建。把每条边的权值设为它所连两点权值的 \(\min\) 或 \(\max\),然后建。
  2. 按点建。从小到大 / 从大到小加入每个点,把它连接的小于 / 大于它的点所在的未连通部分连通。

都是自底向上建。[都要用并查集来维护。]

2024.11.16

6. P4606 [SDOI2018] 战略游戏

无向图摧毁单点影响连通性,显然点双。建圆方树,对每个询问建虚树,要在虚树上统计路径上的圆点个数;只需要在圆方树上预处理根到每个点的圆点个数(我之前(2024.11.16 之前)的代码里是 dis)就很好处理了。注意为了不重不漏,DP 状态的值不统计当前结点是否是圆点。注意最后要加上根的贡献(是否是圆点),并减去询问给出的点的数量(这些点不能摧毁)。

二次排序建虚树,不一定要把 \(1\) 丢进去,也不要习惯性地把 \(1\) 丢进去。二次排序建虚树最后 \(h_1\) 就是虚树的根。

我还不会单调栈建虚树。

2024.11.16

7. P2495 [SDOI2011] 消耗战

虚树 + 树形 DP。板子。

注意建虚树前后 \(k\) 可能会变(丢了个 \(1\) 进去),而且点的顺序会被打乱(按 DFS 序排序)。

注意虚树上的边不需要用倍增(树上 ST 表)或者其他数据结构来求那条路径上的边权的 \(\min\) 来作为权值,而只需要在树上算点到根的最小边权来作为这个点的点权,用点权来 DP 即可。

2024.11.16

8. CF487E Tourists

用圆方树的原因:不能经过重复的点。[在一个点双内,任意两点之间都有至少两条不相交(没有公共点)的路径。] [一定可以找到一条经过的点不重复的路径,使得开头进点双,结尾出点双,且能走过点双中一个给定的结点;这可以感性理解,我还不会证。]于是每个点双的贡献就是它里面的最小点。

考虑单点修改怎么办,一个圆点修改要改与它相邻的方点的权值,有可能会有很多方点。一个思路是根号分治,不知道能不能过。

有另一个更简单且有启发性的思路:单点修改影响相邻点的解决方案:每个方点只记它的子结点的权值 \(\min\),那么每个圆点修改时就只需要考虑父结点,对每个方点用 [multiset] 来维护即可。但注意查询时如果 LCA 是方点,还要考虑 LCA 的父亲的权值。这样做的正确性思考查询的是什么就可以说明。

参考:题解 CF487E 【Tourists】 - 洛谷专栏 (luogu.com.cn)

2024.11.16

9. P7515 [省选联考 2021 A 卷] 矩阵游戏

感觉这道题很有启发性:对于这种信息不全的倒推题,可以先不管某些条件(本题中是范围),钦定一些信息来推出所有的信息,再调整使得不破坏已满足的限制且满足尚未满足的限制。

本题使用差分约束。注意为了满足差分约束的条件(最短路的 [三角形不等式]),我们需要根据奇偶变一些符号。

注意差分约束的最短路初始化阶段的写法,具体见我代码。要用 SPFA,要判负环,负环即无解。

2024.11.16

10. CF888G Xor-MST

对于稠密图(如:完全图)的最小生成树,Boruvka 算法是一种普遍适用的思路。然而不必拘泥于此算法的过程,而可以利用此算法的正确性来灵活地进行类似的贪心。

本题可以直接在 01-Trie 上贪心解决,具体是类似 01-Trie 合并的思路,但本题中可以不合并,直接左边的在右边询问。可以把所有数排序,那么一棵子树对应一段区间,更容易实现。

参考:题解 CF888G 【Xor-MST】 - 洛谷专栏 (luogu.com.cn)

2024.11.16

11. AT_cf17_final_j Tree MST

看洛谷题解区说可以用 Boruvka 算法。

除了 Boruvka 算法,稠密图的最小生成树还有一种做法,就是分割 边集。(也许要求 [边权为正])把边集分成若干个子集,[使得每个子集里面的边带着的点都连通](不知道有没有这个要求)。把每个子集的最小生成树的边都拿去跑最小生成树,就能得到整个图的最小生成树。证明可以用反证法。

对于本题:拆树上两点距离,枚举 LCA,在每个 LCA 处处理每个部分之间的边,用点分治枚举 LCA 以保证复杂度。最后把每次分治时留下的边都拿到一起跑 Kruskal 即可。

参考(分割边集的结论、证明以及本题做法):【题解】AT3611 Tree MST - 洛谷专栏 (luogu.com.cn)

2024.11.16

标签:图论,2024.11,16,短路,分治,笔记,贡献,做法
From: https://www.cnblogs.com/huangkxQwQ/p/18549506

相关文章

  • java学习笔记-面向对象-类的内部构造与对象(2)
    类是一组具有相同属性和行为的对象的抽象。类及类的关系构成了对象模型的主要内容。面向对象编程的主要任务就是定义对象模型中的各个类。1.定义类(class)//定义静态属性--班费//在类中被定义为静态的属性将被所有该类创建的对象所共享staticdoubleclass......
  • 几个有意思的多线程问题 & 有趣现象笔记
    信号量释放的时候线程被带入的问题SemaphoreSlim和多线程使用的时候,.Release()时,应该在新的线程去做Release操作同理,因为Release时会切换到await等待的代码执行,也就是调用SemaphoreSlim.Release的线程被带入到了awaitSemaphoreSlim.WaitAsync()的代码执行,如果是一个......
  • 【学习笔记】Segment Tree Beats/吉司机线段树
    链接区间最值操作HDU-5306支持对区间取\(\min\),维护区间\(\max\),查询区间和。很容易想到一个暴力,我们每一次找出这个区间的最大值\(mx\),如果\(mx>x\),那么暴力修改这个位置的值,否则已经修改完毕,退出,时间复杂度为\(O(n^2\logn)\)。打一打补丁,对线段树上的每一个区间维......
  • _app搭建笔记
    逍遥模拟器端口号:21503(3)adbinstall+包名的绝对路径安装apk包案例:adbinstallE:\dcs\two\app\mojibase.apkE:\dcs\two\app\baiduyuedu_5520.apk(4)活动路径名:aaptdbadgingD:\app\baiduyuedu_3760.apk(5)adbuninstall包名:卸载com.baidu.yuedu包名name='com......
  • 【跟着阿舜学音乐-笔记】1.12和弦功能与进行原理
    七和弦七和弦是三和弦的基础上叠加三音构成的和弦(四个音的和弦)。其中小大七和弦(CmM7)很少运用,因为调内没有小大七和弦,同时听感上也不是很好。注:有另一种和弦命名方式,即三和弦与根音呈大小七度的音组成和弦的命名法,该命名法对比上述命名法有个特例——增大七和弦(增三和弦叠加一......
  • 设计模式学习笔记之七大原则
    设计模式的七大原则开闭原则(OpenClosedPrinciple,OCP)单一职责原则(SingleResponsibilityPrinciple,SRP)里氏代换原则(LiskovSubstitutionPrinciple,LSP)依赖倒转原则(DependencyInversionPrinciple,DIP)接口隔离原则(InterfaceSegregationPrinciple,ISP)合成/聚合复用原则(Co......
  • 人工智能:原理与技术 学习笔记
    Lecture2Supervisedlearning:regression,classification,...Unsupervisedlearning:clustering,dimensionalityreduction,...Thecanonicalmachinelearningproblem:Givenasetoftrainingdata\(\{(x_i,y_i)\}_{i=1}^m\)andalossfunction\......
  • [笔记]Dijkstra算法正确性证明
    最近做了一些题,感觉对算法更深刻的理解是比套板子更深层次的,在这个层次上解决问题,思路会更加清晰。比如P5687[CSP-S2019江西]网格图(题解)这道题就是网格图的最小生成树,解法就建立在普通Kruskal的基础上,当时想了挺久也没想出来,看了题解才豁然开朗。所以各算法总是要回顾回顾的~......
  • The Missing Semester 第一讲MIT笔记
    幕布链接shell命令-幕布echo打印传入参数echohello\Worldecho"helloworld"echo$PATH(找环境变量在哪)date查看时间which查看程序所在的目录pwdpresentworkingdirectory当前所在的工作目录path在windows中路径一般为反斜杠\masOS和Linux不同为斜杠,下为绝对路径......
  • c语言笔记(鹏哥)课件+上课板书汇总(深入指针1)
    深入指针(1)⽬录:一、内存和地址二、指针变量和地址三、取地址操作符四、指针变量类型的意义(这一讲到这)五、const修饰指针六、指针运算七、野指针八、assert断⾔九、指针的使⽤和传址调⽤内存和地址引例:假设有一个宿舍楼,你在一个房间里,宿舍楼里每一间房间都......