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

题面

BZOJ

求仙人掌的直径(两点之间最短路径最大值)

题解

一开始看错题了,以为是求仙人掌中的最长路径。。。

后来发现看错题了一下就改过来了。。

首先和普通的仙人掌\(dp\)是一样的,

对于没有问题的圆圆边,直接做最长链的转移(同时更新\(ans\))

然后对于一个环,把它拎出来单独考虑

首先要对于这个环,计算能够贡献的答案,

然后再用环上的值更新环的最顶点

先考虑怎么更新,这个直接拿环上的点的\(dp\)值,再计算一下这两点之间的最短路(深度差和环大小减深度差的较小值),相加去更新\(dp\)值。

然后考虑一下如何贡献答案,

要求的相当于是\(max(f[i]+f[j]+dist(i,j))\)

而\(dist(i,j)=min(abs(dep[i]-dep[j]),circle\_size-abs(dep[i]-dep[j]))\)

发现维护一个单调队列,按照深度依次进栈,

这样子距离直接可以用深度做差,没有了绝对值

因为可以通过返祖边回去,因此把所有点按照顺序进两次队就可以了

第二次进队的时候给深度加上一个环大小再进队

然后如何保证是环上的最短路?

如果两个深度差已经大于环大小的一半了,那么最短路就不是这一条了

所以直接弹走队首就行了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 55555
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;}e[MAX<<3];
int h[MAX],cnt=1,n,m;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int f[MAX],ans=1,fa[MAX],dep[MAX],dfn[MAX],low[MAX],tim;
int H,T,Q1[MAX<<1],Q[MAX<<1];
void dp(int u,int y)
{
int t=0;
for(int i=y;i!=u;i=fa[i])Q1[++t]=i;Q1[++t]=u;
reverse(&Q1[1],&Q1[t+1]);
for(int i=1;i<=t;++i)Q1[i+t]=Q1[i];
H=1;T=0;
for(int i=1;i<=t+t;++i)
{
while(H<=T&&i-Q[H]>t/2)++H;
if(H<=T)ans=max(ans,f[Q1[i]]+f[Q1[Q[H]]]+i-Q[H]);
while(H<=T&&f[Q1[i]]-i>f[Q1[Q[T]]]-Q[T])--T;
Q[++T]=i;
}
for(int i=y;i!=u;i=fa[i])
f[u]=max(f[u],f[i]+min(dep[i]-dep[u],1+dep[y]-dep[i]));
}
void dfs(int u,int ff)
{
fa[u]=ff;dfn[u]=low[u]=++tim;dep[u]=dep[ff]+1;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(!dfn[v])dfs(v,u),low[u]=min(low[u],low[v]);
else if(v!=ff)low[u]=min(low[u],dfn[v]);
if(low[v]>dfn[u])
ans=max(ans,f[u]+f[v]+1),f[u]=max(f[u],f[v]+1);
}
for(int i=h[u];i;i=e[i].next)
if(fa[e[i].v]!=u&&dfn[u]<dfn[e[i].v])
dp(u,e[i].v);
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;++i)
{
int K=read(),a=read();
for(int j=1;j<K;++j)
{
int b=read();
Add(a,b);Add(b,a);
a=b;
}
}
dfs(1,0);
printf("%d\n",ans);
return 0;
}

【BZOJ1023】仙人掌图(仙人掌,动态规划)的更多相关文章

  1. BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌dp)

    Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3467  Solved: 1438[Submit][Status][Discuss] Descripti ...

  2. BZOJ1023: [SHOI2008]cactus仙人掌图(仙人掌)

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

  3. BZOJ1023 SHOI2008 仙人掌图 仙人掌、单调队列

    传送门 求仙人掌的直径,可以由求树的直径进行拓展,只需要在环上特殊判断. 沿用求树的直径的DP,对于一条不在任何环内的边,直接像树的直径一样转移,然后考虑环的影响. 设环长为\(cir\),在\(df ...

  4. 【bzoj1023】仙人掌图

    [bzoj1023]仙人掌图 题意 给一棵仙人掌,求直径. \(n\leq 100000\) 分析 分析1:[Tarjan]+[环处理+单调队列优化线性dp]+[树形dp] 分开两种情况处理: ①环: ...

  5. bzoj千题计划113:bzoj1023: [SHOI2008]cactus仙人掌图

    http://www.lydsy.com/JudgeOnline/problem.php?id=1023 dp[x] 表示以x为端点的最长链 子节点与x不在同一个环上,那就是两条最长半链长度 子节点与 ...

  6. BZOJ1023:[SHOI2008]cactus仙人掌图(圆方树,DP,单调队列)

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

  7. BZOJ1023:[SHOI2008]仙人掌图——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1023 Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple ...

  8. BZOJ1023[SHOI2008]cactus仙人掌图 【仙人掌DP】

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

  9. 仙人掌图判定及求直径HDU3594 BZOJ1023

    https://wenku.baidu.com/view/ce296043192e45361066f575.html   //仙人掌图基础知识3个判定条件 http://blog.csdn.net/y ...

随机推荐

  1. python os模块详解

    一.Python os模块(Linux环境) 1.1 执行shell命令 os.system('cmd') 执行命令不保存结果 os.popen('command') 执行后返回结果,使用.read( ...

  2. Java工具类——UUIDUtils

    借用一下百度百科的解释,来看一下UUID是什么. UUID含义是通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标准,也是被开源软件基金会 (Ope ...

  3. Django之在Python中调用Django环境

    Django之在Python中调用Django环境 新建一个py文件,在其中写下如下代码: import os if __name__ == '__main__': os.environ.setdef ...

  4. Python之操作MySQL数据库

      一.操作步骤 1.导入pymysql模块 2.建立连接(ip.用户名.密码.数据库名.端口号.字符集.(自动提交参数)) 3.建立游标 4.执行sql语句 (4.需要提交的提交) 5.关闭游标 6 ...

  5. 【问题解决方案】The MathType Dll cannot be found 问题解决方案

    先贴几个可能的方法: 如何解决MathPage.wll或MathType.dll文件找不到问题 The MathType Dll cannot be found 问题解决办法 如果还搞不定,试试卸载重 ...

  6. js this的含义以及讲解

    this关键字是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成. 首先,this总是返回一个对象,简单说,就是返回属性或方法“当前”所在的对象. 下面来两个例子来让大家更 ...

  7. babel(一)

    一.babel npm babel src/index.js -d lib 二.@babel/core   @babel/cli @babel/core  转换语法核心 @babel/cli   执行 ...

  8. [FreeBuff]Trojan.Miner.gbq挖矿病毒分析报告

    Trojan.Miner.gbq挖矿病毒分析报告 https://www.freebuf.com/articles/network/196594.html 竟然还有端口转发... 这哥们.. 江民安全 ...

  9. Unit 1.前端基础之html

    一.什么是html 定义:全称是超文本标记语言(HyperText Markup Language),它是一种用于创建网页的标记语言.标记语言是一种将文本(Text)以及文本相关的其他信息结合起来,展 ...

  10. 使用cmd命令删除文件夹下所有文件

    rmdir 删除整个目录 好比说我要删除 222 这个目录下的所有目录和档案,这语法就是: rmdir /s/q 222 其中: /s 是代表删除所有子目录跟其中的档案. /q 是不要它在删除档案或目 ...