【题意】给定仙人掌图(每条边至多在一个简单环上),求直径(最长的点对最短路径)。n<=50000,m<=10^7。

【算法】DFS树处理仙人掌

【题解】参考:仙人掌相关问题的处理方法(未完待续)

对仙人掌建立DFS树,参考无向图的点双连通分量Tarjan算法,在访问x时容易知道边(x,y)是否属于一个环。

设f[x]表示x点向下延伸的最长链长度,对于不在环上的边(x,y),有f[x]=max{f[y]+1}。统计直径可以在访问每个y时进行ans=max{ans,f[x]+f[y]+1}从而完成子树x对答案的贡献。

对于一个环,只在其DFS树中深度最小的点进行处理(其它点直接忽略环边的存在),假设当前这个点为x,其与深度最大的点y的连边为(x,y)。(这条边只要满足fa[y]≠x&&dfn[y]>dfn[x]就可以找到)

假设这个环有cnt个点,在环上只有距离<=cnt/2的点对可以贡献答案。我们只需要维护每个点和其前面半圈的点构成的点对中的最大值,这可以用单调队列维护。

但这样的话,前半圈的点与前面的点对会少考虑一部分,所以将环延伸半圈,即维护一圈半的点。最后记得枚举整个环更新f[x]。

复杂度O(m)。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
const int maxn=,maxm=;
struct edge{int v,from;}e[maxm];
int first[maxn],tot,fa[maxn],a[maxn],f[maxn],q[maxn],dfn[maxn],low[maxn],ans,dfsnum=,n,m;
void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
void solve(int A,int B){
int cnt=;
for(int i=B;i!=A;i=fa[i])a[++cnt]=f[i];a[++cnt]=f[A];
for(int i=;i<=cnt/;i++)swap(a[i],a[cnt-i+]);
for(int i=cnt+;i<=cnt+(cnt>>);i++)a[i]=a[i-cnt];
int head=,tail=;q[head]=;
for(int i=;i<=cnt+(cnt>>);i++){
if(head<tail&&i-q[head]>cnt/)head++;
ans=max(ans,a[i]+a[q[head]]+i-q[head]);
while(head<tail&&a[i]-i>=a[q[tail-]]-q[tail-])tail--;
q[tail++]=i;
}
for(int i=;i<=cnt;i++)f[A]=max(f[A],a[i]+min(i-,cnt-i+));
}
void dfs(int x,int father){
dfn[x]=low[x]=++dfsnum;f[x]=;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=father){
int y=e[i].v;
if(!dfn[y]){
fa[y]=x;
dfs(y,x);
low[x]=min(low[x],low[y]);
}else low[x]=min(low[x],dfn[y]);
if(low[y]>dfn[x]){
ans=max(ans,f[x]+f[y]+);
f[x]=max(f[x],f[y]+);
}
}
for(int i=first[x];i;i=e[i].from)
if(e[i].v!=father&&fa[e[i].v]!=x&&dfn[e[i].v]>dfn[x])solve(x,e[i].v);
}
int main(){
n=read();m=read();
for(int i=;i<=m;i++){
int k=read(),u=read();
for(int j=;j<=k;j++){
int v=read();
insert(u,v);insert(v,u);
u=v;
}
}
ans=;
dfs(,);
printf("%d",ans);
return ;
}

【BZOJ】1023: [SHOI2008]cactus仙人掌图 静态仙人掌(DFS树)的更多相关文章

  1. bzoj 1023: [SHOI2008]cactus仙人掌图 tarjan缩环&&环上单调队列

    1023: [SHOI2008]cactus仙人掌图 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1141  Solved: 435[Submit][ ...

  2. 【刷题】BZOJ 1023 [SHOI2008]cactus仙人掌图

    Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的 ...

  3. bzoj 1023: [SHOI2008]cactus仙人掌图 2125: 最短路 4728: 挪威的森林 静态仙人掌上路径长度的维护系列

    %%% http://immortalco.blog.uoj.ac/blog/1955 一个通用的写法是建树,对每个环建一个新点,去掉环上的边,原先环上每个点到新点连边,边权为点到环根的最短/长路长度 ...

  4. BZOJ 1023: [SHOI2008]cactus仙人掌图 | 在仙人掌上跑DP

    题目: 求仙人掌直径 http://www.lydsy.com/JudgeOnline/problem.php?id=1023 题解: 首先给出仙人掌的定义:满足所有的边至多在一个环上的无向联通图 我 ...

  5. bzoj 1023 [SHOI2008]cactus仙人掌图 ( poj 3567 Cactus Reloaded )——仙人掌直径模板

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1023 http://poj.org/problem?id=3567 因为lyd在讲课,所以有 ...

  6. bzoj 1023: [SHOI2008]cactus仙人掌图

    这道题是我做的第一道仙人掌DP,小小纪念一下…… 仙人掌DP就是环上的点环状DP,树上的点树上DP.就是说,做一遍DFS,DFS的过程中处理出环,环上的点先不DP,先把这些换上的点的后继点都处理出来, ...

  7. BZOJ.1023.[SHOI2008]cactus仙人掌图(DP)

    题目链接 类似求树的直径,可以用(类似)树形DP求每个点其子树(在仙人掌上就是诱导子图)最长链.次长链,用每个点子节点不同子树的 max{最长链}+max{次长链} 更新答案.(不需要存次长链,求解过 ...

  8. bzoj 1023: [SHOI2008]cactus仙人掌图【tarjan+dp+单调队列】

    本来想先求出点双再一个一个处理结果写了很长发现太麻烦 设f[u]为u点向下的最长链 就是再tarjan的过程中,先照常处理,用最长儿子链和次长儿子链更新按ans,然后处理以这个点为根的环,也就是这个点 ...

  9. 【BZOJ1023】仙人掌图(仙人掌,动态规划)

    [BZOJ1023]仙人掌图(仙人掌,动态规划) 题面 BZOJ 求仙人掌的直径(两点之间最短路径最大值) 题解 一开始看错题了,以为是求仙人掌中的最长路径... 后来发现看错题了一下就改过来了.. ...

随机推荐

  1. VMware12 pro装unlocker207补丁后依然没有apple mac选项,问题解决

    把VMware所有的服务先停止,任务管理器里面的也停止.然后再安装unlocker207补丁就行了.亲测.

  2. C 语言疑难杂症 [转:http://blog.chinaunix.net/uid-20688544-id-1894880.html]

    无聊在网上找了些C语言的东东练一下手,竟然发现其实还有好多细节之前,没注意到,该好好复习一下先. 解决掉的问题先不发出来,把疑问的先做个笔记,过几天解决了就回来修改补上.   #include < ...

  3. 第142天:Size Marks下载安装和使用方法

    Size Marks下载安装使用方法 一.下载安装 1.下载Size marks:链接: https://pan.baidu.com/s/1breyMf1 密码: fjsn 2. 复制 Size Ma ...

  4. 对xml的操作使用的类XElement的使用

    操作xml的类比较多,发现XElement类操作xml极其方便,下面列举一些操作方法 1.创建xml XElement xml = new XElement("root", new ...

  5. ZOJ3113_John

    这个题目是一个典型的Anti_Sg.我也不知道为什么这么叫,呵呵,反正大家都这么叫,而且我也是听别人说,看别人的日志自己才知道的. 题目的意思是给你不同颜色的石子,每次可以去一种颜色的石子若干个(至少 ...

  6. dom对象转成jquery对象时候 变成数组 jquery转成dom时候 取数组第一个

  7. An In-Depth Look at the HBase Architecture--转载

    原文地址:https://www.mapr.com/blog/in-depth-look-hbase-architecture In this blog post, I’ll give you an ...

  8. bzoj1061-[Noi2008]志愿者招募-单纯形 & 费用流

    有\(n\)天,\(m\)类志愿者,一个第\(i\)类志愿者可以从第\(s_i\)天工作到第\(t_i\)天,第\(i\)天工作的志愿者不少于\(b_i\)个.每一类志愿者都有单价\(c_i\),问满 ...

  9. 题解 P1423 【小玉在游泳】

    这道题可以用简单的蒟蒻do-while循环,方式:直到型 因为是萌新/蒟蒻,所以并不知道这道题的时间/空间复杂度是多大 脚踩std(^▽^)摩擦 #include <iostream> # ...

  10. C++解析(9):关于const和引用的疑问

    0.目录 1.关于const的疑问 2.关于引用的疑问 2.1 引用与指针 2.2 从C++语言与C++编译器角度看引用 2.3 从工程项目开发看引用 3.小结 1.关于const的疑问 const什 ...