P4244 [SHOI2008]仙人掌图 II
仙人掌直径,以前好像模拟赛的时候做到过一道基环树的直径,打了个很麻烦的然而还错了……今天才发现那就是这个的弱化版啊……
如果是树的话用普通的dp即可,记\(f[u]\)表示\(u\)往下最长能伸多少。我们用一个类似tarjan的做法,在dfs的过程中记录dfn和low,如果某条边不在环内,那么这条边我们直接按树形dp转移。
否则的话,当我们做完这整个环的时候,考虑如何更新环的顶点\(f[u]\),设某个点为\(v\),那么有\(f[u]=max(f[u],f[v]+min(dep[v]-dep[u],circle\_size-dep[v]+1))\)
然后这个环上的两个顶点可能构成答案。那么维护一个单调队列,破环成链跑一遍就行了
//minamoto
#include<bits/stdc++.h>
#define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
#define go(u) for(register int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int max(const int &x,const int &y){return x>y?x:y;}
inline int min(const int &x,const int &y){return x<y?x:y;}
char buf[1<<21],*p1=buf,*p2=buf;
using namespace std;
int read(){
int res,f=1;char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=50005;
struct eg{int v,nx;}e[N<<3];int head[N],tot;
inline void add(int u,int v){e[++tot]={v,head[u]},head[u]=tot;}
int n,m,f[N],ans=1,dep[N],fa[N],dfn[N],low[N],tim;
int h,t,q1[N<<1],q[N];
void dp(int u,int y){
int top=0;
for(register int i=y;i!=u;i=fa[i])q1[++top]=i;q1[++top]=u;
reverse(q1+1,q1+1+top);fp(i,1,top)q1[i+top]=q1[i];
h=1,t=0;
fp(i,1,top+top){
while(h<=t&&i-q[h]>top/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(register int i=y;i!=u;i=fa[i])
f[u]=max(f[u],f[i]+min(dep[i]-dep[u],dep[y]-dep[i]+1));
}
void dfs(int u,int fat){
fa[u]=fat,dfn[u]=low[u]=++tim,dep[u]=dep[fat]+1;
go(u)if(v!=fat){
if(!dfn[v])dfs(v,u),low[u]=min(low[u],low[v]);
else 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);
}
go(u)if(fa[v]!=u&&dfn[u]<dfn[v])dp(u,v);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
fp(i,1,m){
int k=read(),a=read(),b;
fp(j,1,k-1)b=read(),add(a,b),add(b,a),a=b;
}
dfs(1,0);printf("%d\n",ans);return 0;
}
P4244 [SHOI2008]仙人掌图 II的更多相关文章
- 洛谷 P4244 [SHOI2008]仙人掌图 II 解题报告
P4244 [SHOI2008]仙人掌图 II 题目背景 题目这个II是和SHOI2006的仙人掌图区分的,bzoj没有. 但是实际上还是和bzoj1023是一个题目的. 题目描述 如果某个无向连通图 ...
- 洛谷P4244 [SHOI2008]仙人掌图 II
传送门 首先不考虑带环的仙人掌,如果只是一棵普通的树,可以通过dp求每棵子树中的最长链和次长链求树的直径. 那么如果dfs的时候遇到了环,应该用环上的两点挂着的最长链加上两点间的距离来更新树的直径,并 ...
- [SHOI2008]仙人掌图 II——树形dp与环形处理
题意: 给定一个仙人掌,边权为1 距离定义为两个点之间的最短路径 直径定义为距离最远的两个点的距离 求仙人掌直径 题解: 类比树形dp求直径. f[i]表示i向下最多多长 处理链的话,直接dp即可. ...
- [SHOI2008]仙人掌图
[SHOI2008]仙人掌图 LG传送门 还不会仙人掌的同学可以看看我对仙人掌知识的一些梳理. 题意就是求仙人掌的直径,直径定义为图中最短路径最长的两点间的最短路径长度. 按照套路,先考虑求树的直径我 ...
- SHOI2008仙人掌图(tarjan+dp)
Solution 好题啊没的说. 本题需要求出仙人掌的直径,但仙人掌是一个带有简单环的一张图无法直接用树形dp求解,但它有一个好东西就是没有类似环套环的东西,所以我们在处理时就方便了一些. 思路:ta ...
- BZOJ1023:[SHOI2008]仙人掌图——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1023 Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple ...
- BZOJ1023 SHOI2008 仙人掌图 仙人掌、单调队列
传送门 求仙人掌的直径,可以由求树的直径进行拓展,只需要在环上特殊判断. 沿用求树的直径的DP,对于一条不在任何环内的边,直接像树的直径一样转移,然后考虑环的影响. 设环长为\(cir\),在\(df ...
- Luogu 4244 [SHOI2008]仙人掌图
BZOJ 1023 如果我们把所有的环都缩成一个点,那么整张图就变成了一棵树,我们可以直接$dp$算出树的直径. 设$f_x$表示$x$的子树中最长链的长度,那么对于$x$的每一个儿子$y$,先用$f ...
- 【题解】SHOI2008仙人掌图
本质上还是树形dp.建立圆方树,遇到圆点的时候直接求(和树形dp一样即可),遇到方点做中转点的时候要考虑会从圆的另一侧通过(需满足最短路径的原则).原本是对于圆上的点进行 \(n^{2}\) 的匹配, ...
随机推荐
- onos控制器通过REST API下发流表
onos控制器REST API地址:http://192.168.43.14:8181/onos/v1/docs/ stream书写格式: { "id": "675540 ...
- Spring Boot - how to configure port
https://stackoverflow.com/questions/21083170/spring-boot-how-to-configure-port
- 学习日常笔记<day09>Http协议
1 Http协议入门 1.1 什么是http协议 http协议: 对浏览器客户端 和 服务器端 之间数据传输的格式规范 1.2 查看http协议的工具 1)使用火狐的firebug插件(右键-> ...
- 【Windows系统】-- 远程桌面时,WIN键被锁定
问题重现: 在对远程机器进行操作的时候,按键时会自动变成WIN组合键,比如:你按D的效果为[WIN+D]组合键的效果 就是切换到桌面,按E就是[WIN+E]组合键的效果,就是打开资源管理器. 解决方案 ...
- 使用URL Rewrite实现网站伪静态
下载urlwrite包 将urlrewrite-***.jar复制到web应用lib文件夹下 web.xml中配置URL Rewrite: 例: <filter> <filter-n ...
- Windows系统下查看已共享的文件夹的方法
电脑使用时间比较长,共享过好几次文件夹,现在想取消共享,但共享文件夹的路径隐藏得太深,要怎么样才能快速找到共享文件夹的实际路径呢?” “其实现在单位常见的方法都是用网上邻居的共享文件夹,共享的文件夹也 ...
- JAVA 流程控制之选择语句
在程序设计时,有三种基本技术可以改变程序的流程控制: 调用方法: 选择: 循环. 在这里,我们主要来讲讲选择语句. JAVA中的选择语句与C语言中的基本相同,包括: if 语句: if/else 语句 ...
- Unix网络编程 之 socket基础
基本结构 (这部分的地址均为网络地址<网络字节序>) 1.struct sockaddr:通用套接字地址结构 此结构用于存储通用套接字地址. 数据结构定义: typedef unsigne ...
- 数学之路-python计算实战(21)-机器视觉-拉普拉斯线性滤波
拉普拉斯线性滤波,.边缘检測 . When ksize == 1 , the Laplacian is computed by filtering the image with the follow ...
- iOS单例设计模式具体解说(单例设计模式不断完好的过程)
在iOS中有非常多的设计模式,有一本书<Elements of Reusable Object-Oriented Software>(中文名字为<设计模式>)讲述了23种软件设 ...