题目地址
算法一
估计大家应该不会被仙人掌吓到而直接
妈妈我不会处理图的问题怎么办?
有
算法二
有
最短路算法
由于时限和数据都很令人感动,这些数据其实用
更好的做法
考虑仙人掌图的
对每个询问的每个询问点,我们都遍历一遍,时间复杂度为
算法三
有
用
考虑更新答案,所有询问点的
经过一个环的最短路径一定是由两条环以外的路径(可以长度为0)和一条环上的路径组成,我们按顺序取出环上的边,并且复制一份接在后面,形成一条链。对于链上的点
算法四
对于树的情况,可以使用虚树。
虚树的建立方法之一是,对询问点按
然后在虚树上
时空复杂度均为
此外时间复杂度可以通过更大的代码复杂度降为
算法五
对于树的情况,还可以用树分治解决。
一种较方便的树分治的做法是,先建立好树分治结构,然后对每一个询问,先将点去重。接着对于每一个树分治结构中的节点(对应一棵子树
但是这个做法由于要预先存储结构,时间空间常数都比较大。
还有一种做法是,询问和树一起分治,这个很好理解,无非就是把两个过程合并了,每一次要处理的是一棵子树和一个询问序列,这个序列只保留所有存在询问点在该子树中的询问,并且每个询问只保留在该子树中的询问点,然后处理询问的方法如同前面所述。
时空复杂度均为
UPD:树上迭代两次求最远点即可,最远点可以直接枚举然后
算法六
对于树的情况,如果你只会虚树或者树分治,对于仙人掌你肯定也只能这么做了。
如果我们能建立“虚仙人掌”,肯定可以解决这个问题。
我们想一想就能想清楚虚仙人掌的一种最笨但是也绝对正确并且可以通过这题的建立方法,先按
根据上述结论,连虚树上的边时,可以将虚仙人掌上的环边和树边一视同仁,统统连它们两个端点在原仙人掌上的最短路径长度。但是这个最短路径长度和树上不同,树上可以直接用离根的距离减一减,仙人掌上就不是这么简单了,离根的最短路长度不具有可减性。是,我们可以用动态仙人掌。但是这样代码复杂度太高。我们考虑一下,如果树上有一个值也不具有可减性,比如路径边权最小值,你会怎么弄?一种方法就是倍增。对仙人掌也这么弄,考虑动态仙人掌维护生成树法的思想,我们记录每个点到它第
UPD:好像可以记录到根的距离,然后用特殊的方法处理一下就可以直接减了。总之实现上有各种技巧优化时间复杂度和代码复杂度,感觉标程就是个逗比啊TAT......
实际上,std的方法和上述方法有细节上的差异,如果
总之这个算法可以非常愉悦的跑出100分, 时空复杂度均为
提交记录在这里。
算法七
对于树分治,我们显然也可以想办法把它搞到仙人掌上,也就是用仙人掌分治来解决问题,实现细节和树分治大同小异,每一次去掉一个点时,先把它弄成仙人掌的根,然后断开它连的所有割边,以及所有它所在环的环边,每一次选一个进行上述操作后,剩下来的子仙人掌中大小最大的最小的点来分治即可(其实为了方便我写的程序不一定能取出最小,但绝对剩下来的子仙人掌中大小最大的不超过
处理每个询问时,根可能连着不少的环。对一个点(除了根),如果在某一个环
时空复杂度均为
解法八
松爷给出了另外一种解法,详见http://wangyisong1996.is-programmer.com/user_files/wangyisong1996/File/zjoi2015/cactus-slides/wys-cactus-slides.html#/6
AC代码:
http://uoj.ac/submission/13387
http://uoj.ac/submission/13388
第一份的空间复杂度是
此外,仙人掌分治和虚仙人掌都可以在线,前者在线情况应该会TLE甚至可能MLE(至少我的写法如此= =b),后者本身就可以在线。这种做法就没什么简单办法做到在线了= =b。
解法九
waltz给出了另外一种解法:http://uoj.ac/submission/13649
时间空间代码量都完虐我啊orz......
这个做法是对每个环,新建一个点,向环上每个点连长度为它到环的根的最短路径长度的边,如果对新树dfs,那么每个点到它的任意非新建祖先的最短路径长度就是它们之间在树上的距离,对于lca不是新建点的两个点最短路长度就是它们之间在树上的距离,是新建点的话,在树上的距离也不会小于真实距离,但我们可以单独取出环再单调队列来解决环的问题。这道题成功降级为符合人民大众胃口的既无思考难度也无代码难度的傻逼题。跪烂waltz!
基于这个思路,也许很多仙人掌上问题可能会有更简单的做法?
乱搞
我们发现对于树的情况,直径就是任取一个点)
另外我们还可以多次枚举点做根,然后设法求得经过根的最长路径,由于答案路径可能很长,一旦取到了一个答案路径上的点做根就可以求出正确答案。但是一旦答案路径比较短,这个算法就不靠谱了。并且这个算法没法较好的判断是否已经是当前答案已经正确。
如果你通过各种方法乱搞过了,你就可以好好感受一下
后记
其实这个题如果出成每对点的最短距离和的话,是可以避免乱搞的,而且不难实现,但是由于奇怪的原因,我没有把它改成这样。
在出题人想出一个原始的算法之后,算法又其他人不断被改进,长江后浪推前浪。感觉我从这道题的出题经历中感受到了科技的进步。
5s的时限真是太良心了233,主要是为了欢迎各种奇葩做法。