【BZOJ】1023: [SHOI2008]cactus仙人掌图 静态仙人掌(DFS树)
【题意】给定仙人掌图(每条边至多在一个简单环上),求直径(最长的点对最短路径)。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树)的更多相关文章
- bzoj 1023: [SHOI2008]cactus仙人掌图 tarjan缩环&&环上单调队列
1023: [SHOI2008]cactus仙人掌图 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1141 Solved: 435[Submit][ ...
- 【刷题】BZOJ 1023 [SHOI2008]cactus仙人掌图
Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的 ...
- bzoj 1023: [SHOI2008]cactus仙人掌图 2125: 最短路 4728: 挪威的森林 静态仙人掌上路径长度的维护系列
%%% http://immortalco.blog.uoj.ac/blog/1955 一个通用的写法是建树,对每个环建一个新点,去掉环上的边,原先环上每个点到新点连边,边权为点到环根的最短/长路长度 ...
- BZOJ 1023: [SHOI2008]cactus仙人掌图 | 在仙人掌上跑DP
题目: 求仙人掌直径 http://www.lydsy.com/JudgeOnline/problem.php?id=1023 题解: 首先给出仙人掌的定义:满足所有的边至多在一个环上的无向联通图 我 ...
- bzoj 1023 [SHOI2008]cactus仙人掌图 ( poj 3567 Cactus Reloaded )——仙人掌直径模板
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1023 http://poj.org/problem?id=3567 因为lyd在讲课,所以有 ...
- bzoj 1023: [SHOI2008]cactus仙人掌图
这道题是我做的第一道仙人掌DP,小小纪念一下…… 仙人掌DP就是环上的点环状DP,树上的点树上DP.就是说,做一遍DFS,DFS的过程中处理出环,环上的点先不DP,先把这些换上的点的后继点都处理出来, ...
- BZOJ.1023.[SHOI2008]cactus仙人掌图(DP)
题目链接 类似求树的直径,可以用(类似)树形DP求每个点其子树(在仙人掌上就是诱导子图)最长链.次长链,用每个点子节点不同子树的 max{最长链}+max{次长链} 更新答案.(不需要存次长链,求解过 ...
- bzoj 1023: [SHOI2008]cactus仙人掌图【tarjan+dp+单调队列】
本来想先求出点双再一个一个处理结果写了很长发现太麻烦 设f[u]为u点向下的最长链 就是再tarjan的过程中,先照常处理,用最长儿子链和次长儿子链更新按ans,然后处理以这个点为根的环,也就是这个点 ...
- 【BZOJ1023】仙人掌图(仙人掌,动态规划)
[BZOJ1023]仙人掌图(仙人掌,动态规划) 题面 BZOJ 求仙人掌的直径(两点之间最短路径最大值) 题解 一开始看错题了,以为是求仙人掌中的最长路径... 后来发现看错题了一下就改过来了.. ...
随机推荐
- .net 错误处理
第一步在页面中写OnError方法: protected override void OnError(EventArgs e) { Exception ex = Server.GetLastError ...
- 敏捷开发之Scrum站立会议
Scrum是迭代式增量软件开发过程,通常用于敏捷开发.站立会议通常指Scrun方法中的每日站立会议.顾名思义,是每天以站姿的方式召开的会议.以下从功能及要点方面对其进行解释说明: 功能: 1. ...
- Mac 常用快捷键整理
Mac下常用的快捷键: Command+W 将当前窗口关闭(可以关闭Safari标签栏,很实用) Command+Option+M 将所有窗口最小化 Command+Q 关闭当前应用程序(相当于Doc ...
- mysql中联合查询
联合查询union 一个翻译问题的解释: 在mysql的手册中,将连接查询(Join)翻译为联合查询: 而联合查询(union),没有明确翻译. 但: 在通常的书籍或文章中,join被翻译为“连接”查 ...
- 我以前不知道的 Session
之前只知道 Session 是服务器与客户端的一个会话,有默认过期时间,是服务器端的技术,与之对应的是 Cookie 技术,是客户端技术. 下面的几点是之前不知道的:[或者是忘了] 1 . Sessi ...
- 怎么用JavaScript实现tab切换
先看一下代码实现后的最终效果: 用JavaScript实现思路很简单,就是先把所有的内容隐藏,点击标题对应的内容显示, css代码如下: <style type="text/css&q ...
- 第110天:Ajax原生js封装函数
一.Ajax的实现主要分为四部分: 1.创建Ajax对象 // 创建ajax对象 var xhr = null; if(window.XMLHttpRequest){ xhr = new XMLHtt ...
- SQL中INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN区别
sql中的连接查询有inner join(内连接).left join(左连接).right join(右连接).full join(全连接)四种方式,它们之间其实并没有太大区别,仅仅是查询出来的结果 ...
- bzoj3663/4660CrazyRabbit && bzoj4206最大团
题意 给出平面上N个点的坐标,和一个半径为R的圆心在原点的圆.对于两个点,它们之间有连边,当且仅当它们的连线与圆不相交.求此图的最大团. 点数<=2000,坐标的绝对值和半径<=5000. ...
- P1065 作业调度方案
题目描述 我们现在要利用m台机器加工n个工件,每个工件都有m道工序,每道工序都在不同的指定的机器上完成.每个工件的每道工序都有指定的加工时间. 每个工件的每个工序称为一个操作,我们用记号j−k表示一个 ...