http://www.lydsy.com/JudgeOnline/problem.php?id=1023 Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌 图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路. 举例来说,上面的第一个例子是一张仙人图,而第二个不是——注意到它有三条简单回路:(4,3,2,1,6,5,4).(7,8,9,10,2,3,7)以及(4,3,7,8,9,10,2,1,…
传送门 求仙人掌的直径,可以由求树的直径进行拓展,只需要在环上特殊判断. 沿用求树的直径的DP,对于一条不在任何环内的边,直接像树的直径一样转移,然后考虑环的影响. 设环长为\(cir\),在\(dfs\)树上,环对应的链的链顶为\(top\),链底为\(bot\),也就是说返祖边为\((top,bot)\),点\(x\)在\(dfs\)树上的深度为\(dep_x\). 在统计环上的点之间的转移和贡献之前,先把环上所有点的子仙人掌的贡献统计好. 环上的转移直接通过方程式\(dp_{top} \l…
[BZOJ1023]仙人掌图(仙人掌,动态规划) 题面 BZOJ 求仙人掌的直径(两点之间最短路径最大值) 题解 一开始看错题了,以为是求仙人掌中的最长路径... 后来发现看错题了一下就改过来了.. 首先和普通的仙人掌\(dp\)是一样的, 对于没有问题的圆圆边,直接做最长链的转移(同时更新\(ans\)) 然后对于一个环,把它拎出来单独考虑 首先要对于这个环,计算能够贡献的答案, 然后再用环上的值更新环的最顶点 先考虑怎么更新,这个直接拿环上的点的\(dp\)值,再计算一下这两点之间的最短路(…
P4244 [SHOI2008]仙人掌图 II 题目背景 题目这个II是和SHOI2006的仙人掌图区分的,bzoj没有. 但是实际上还是和bzoj1023是一个题目的. 题目描述 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路.显然,仙人图上的每条边,或者是这张仙人图的桥(bridge),或者在且仅在一个简单回路里,两者必居其一.定义在图上两点之间的距离为这两点…
[bzoj1023]仙人掌图 题意 给一棵仙人掌,求直径. \(n\leq 100000\) 分析 分析1:[Tarjan]+[环处理+单调队列优化线性dp]+[树形dp] 分开两种情况处理: ①环:把整个环搞出来,进行dp,见bzoj1791 方法差不多,只是环处理+单调队列维护dp. ②不是环:直接dp 分析2:圆方树 这个东西还没有学... 反正文章先放在这里吧. http://immortalco.blog.uoj.ac/blog/1955…
[SHOI2008]仙人掌图 LG传送门 还不会仙人掌的同学可以看看我对仙人掌知识的一些梳理. 题意就是求仙人掌的直径,直径定义为图中最短路径最长的两点间的最短路径长度. 按照套路,先考虑求树的直径我们是怎么做的.设\(f[i]\)表示\(i\)往下最长链的长度,\(j\)是\(i\)的儿子,转移和更新答案就是(我习惯用\(o\)表示答案): \[f[i] = max\{f[j]\} + 1 \qquad o = max\{f[i] + f[j] + 1\}\] 考虑放到仙人掌上,对于树边直接转…
题意: 给定一个仙人掌,边权为1 距离定义为两个点之间的最短路径 直径定义为距离最远的两个点的距离 求仙人掌直径 题解: 类比树形dp求直径. f[i]表示i向下最多多长 处理链的话,直接dp即可. 处理环的话,类似点双tarjan,把环上的点都拉出来. 先考虑拼接更新答案.断环成链复制一倍,为了保证最短路,答案必须只能是f[i]+f[j]+i-j (i-len/2<=j<i) 单调队列优化. 直接i-j即可,另一半的绕环会在复制后的那里处理. 然后更新f[x],直接找环上其他的元素,距离就是…
Solution 好题啊没的说. 本题需要求出仙人掌的直径,但仙人掌是一个带有简单环的一张图无法直接用树形dp求解,但它有一个好东西就是没有类似环套环的东西,所以我们在处理时就方便了一些. 思路:tarjan找环,对于不在环上的边或点,树形dp求解,对于每个环,dp求解(单调队列优化), 下面主要说一下代码的实现, void tarjan(int u,int ff) { dfn[u]=low[u]=++top; deep[u]=deep[ff]+; for(int i=head[u];i;i=a…
本质上还是树形dp.建立圆方树,遇到圆点的时候直接求(和树形dp一样即可),遇到方点做中转点的时候要考虑会从圆的另一侧通过(需满足最短路径的原则).原本是对于圆上的点进行 \(n^{2}\) 的匹配,果断超时.但没有发现 \(n ^ {2}\) 的dp明显是一个可以单调队列优化的dp.所以在遇上难解决的问题的时候,一定要融会贯通地思考.有一个细节:将圆复制一下可以去掉 \(max\)造成的影响,dp就十分方便了. #include <bits/stdc++.h> using namespace…
BZOJ 1023 如果我们把所有的环都缩成一个点,那么整张图就变成了一棵树,我们可以直接$dp$算出树的直径. 设$f_x$表示$x$的子树中最长链的长度,那么对于$x$的每一个儿子$y$,先用$f_x + f_y + 1$更新答案,再用$f_y + 1$更新$f_x$. 考虑加入环的情况,保留这个$f_x$的设定.我们可以按照搜索顺序把环上第一个搜到的点看成环的“根”,然后用这个“根”来计算这个环. 假设有环$1, 2, 3, ..., m$,$1$是环的“根”,那么我们可以用$f_i +…