[NEERC2007][SHOI2008]Cactus Reloaded
题目大意:
给你一个仙人掌,求图中相距最远的点对之间的距离。
思路:
Tarjan+DP。
我们先考虑一个树的情况。
设用far[u]表示点u出发到其子树中叶子节点的最大距离,若v为u的子结点,很显然far[u]=max{far[v]}+1。
而对于经过点u的简单路径,最长的一条肯定是max{far[v]+far[w]+2},且u≠w。
很显然我们只需要DFS一遍,然后随便转移即可。
考虑一下仙人掌和树有什么不同。
很显然仙人掌就是在一棵树上加了几条边,使得图中出现了一些环,而且不会有边同时出现在两个环中。
我们不妨先把原图的环去掉某一个边,使得剩下的图是一棵树,很容易处理出树上的情况。
处理到当前环中最后一条边时,再单独对这个环进行DP。
考虑这个环上的每一棵外向树,设u和v是这个环上的两个结点,那么far[u]+far[v]+dis(u,v)就是一个可能的答案。
如何让这个答案最大化?
对于每一个点u,我们可以枚举每一个v来得到一个可能的答案,而要让答案尽可能大,似乎可以用单调队列来转移。
但唯一的问题是,现在u和v是再一个环上,他们的距离是不会单调递增的,也就是说你按顺序枚举每一个点,可能先越来越远再越来越近。
对于这种情况,我们把环复制一遍来转移,维护队列的时候要判断一下当前待更新的点u和用来更新的点v距离是不是超过环长的一半。
最后再更新一下环上高度最高的点对应的far值。
设环的大小为size,最高点为top,那么far[top]=max(far[top],max{far[v]+dis(top,v)})。
这时候要注意一下,前面DFS(Tarjan)里面,far的转移要判断一下,low[v]是不是大于等于dfn[u],如果不是,说明现在是在环上。
所以不能直接更新,不然后面环上DP可能会重复。
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=;
std::vector<int> e[N];
int far[N],par[N],ans;
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
inline void dp(const int &top,const int &end,const int &size) {
static int cir[N*];
static std::deque<int> q;
for(register int i=size,v=end;i;i--) {
cir[size+i]=cir[i]=far[v];
v=par[v];
}
q.push_back();
for(register int i=;i<=size*;i++) {
if(i-q.front()>size/) q.pop_front();
ans=std::max(ans,cir[i]+cir[q.front()]+i-q.front());
while(!q.empty()&&cir[q.back()]-q.back()<=cir[i]-i) q.pop_back();
q.push_back(i);
}
q.clear();
for(register int i=;i<=size;i++) {
far[top]=std::max(far[top],cir[i]+std::min(i-,size-i+));
}
}
void tarjan(const int &x,const int &par) {
static int low[N],dfn[N],dep[N],cnt;
::par[x]=par;
dep[x]=dep[par]+;
low[x]=dfn[x]=++cnt;
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
if(!dfn[y]) {
tarjan(y,x);
low[x]=std::min(low[x],low[y]);
} else {
low[x]=std::min(low[x],dfn[y]);
}
if(dfn[x]<low[y]) {
ans=std::max(ans,far[x]+far[y]+);
far[x]=std::max(far[x],far[y]+);
}
}
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(x!=::par[y]&&dfn[x]<dfn[y]) {
dp(x,y,dep[y]-dep[x]+);
}
}
}
int main() {
getint();
for(register int m=getint();m;m--) {
for(register int k=getint(),u=getint();--k;) {
const int v=getint();
add_edge(u,v);
u=v;
}
}
tarjan(,);
printf("%d\n",ans);
return ;
}
[NEERC2007][SHOI2008]Cactus Reloaded的更多相关文章
- bzoj 1023: [SHOI2008]cactus仙人掌图 tarjan缩环&&环上单调队列
1023: [SHOI2008]cactus仙人掌图 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1141 Solved: 435[Submit][ ...
- bzoj千题计划113:bzoj1023: [SHOI2008]cactus仙人掌图
http://www.lydsy.com/JudgeOnline/problem.php?id=1023 dp[x] 表示以x为端点的最长链 子节点与x不在同一个环上,那就是两条最长半链长度 子节点与 ...
- bzoj 1023 [SHOI2008]cactus仙人掌图 ( poj 3567 Cactus Reloaded )——仙人掌直径模板
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1023 http://poj.org/problem?id=3567 因为lyd在讲课,所以有 ...
- bzoj1023 [SHOI2008]cactus仙人掌图 & poj3567 Cactus Reloaded——求仙人掌直径
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1023 http://poj.org/problem?id=3567 仙人掌!直接模仿 ...
- 1023: [SHOI2008]cactus仙人掌图 - BZOJ
Description如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路 ...
- [SHOI2008]cactus仙人掌图
[题目描述] 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路. 举例 ...
- BZOJ1023:[SHOI2008]cactus仙人掌图(圆方树,DP,单调队列)
Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus). 所谓简单回路就是指在图上不重复经过任何一个顶点 ...
- 【刷题】BZOJ 1023 [SHOI2008]cactus仙人掌图
Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的 ...
- [bzoj1023][SHOI2008]cactus 仙人掌图 (动态规划)
Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回 ...
随机推荐
- [hdu 3949]线性基+高斯消元
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 一开始给做出来的线性基wa了很久,最后加了一步高斯消元就过了. 之所以可以这样做,证明如下. 首 ...
- 状压DP初识~~炮兵阵地
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 31718 Accepted: 12253 Descriptio ...
- java的URI和URL到底是什么
在我们做开发时,经常有URI和URL弄混的问题,如果当时直接看URI和URL的源码就不可能弄混.首先我总结一下URI和URL的关系:他们的关系是:URL是一种特殊的URI,是URI包括URL, 下面用 ...
- NodeJS概述
NodeJS中文API 一.概述 Node.js 是一种建立在Google Chrome’s v8 engine上的 non-blocking (非阻塞), event-driven (基于事件的) ...
- checkbox和后面文字无法居中对齐的解决方案
制作前端页面时,表单的页面中都存在表单元素与提示文字无法对齐的问题.下面是针对这一问题的解决方案: 先上结果图看效果,吼吼~ 最上面两个是经过css处理后的效果,已经居中对齐了哦~,最后一个是没有处理 ...
- 关于ora-12154:TNS:could not resolve the connect identifier specified
一:前言 刚刚出来实习,在公司配的电脑里面装的oracle和PL SQL时一次性就搞定,但是在自己的电脑上装了就出现这个问题,刚刚在网上看了下,所以自己就写份记载吧! 二: 在打开PLSQL Deve ...
- pageContext对象的用法详述
pageContext对象 这个对象代表页面上下文,该对象主要用于访问JSP之间的共享数据. pageContext是PageContext类的实例,使用pageContext可以访问page.re ...
- AtCoder Regular Contest 082 E
Problem Statement You are given N points (xi,yi) located on a two-dimensional plane. Consider a subs ...
- laravel 获得各个根文件夹路径的方法及路由的一些使用
各个根文件夹路径的方法 APP目录: app_path(); config目录: config_path(); public目录: public_path(); storage目录: storage_ ...
- WIN8.1优化
用WIN8.1至今,总结的所有优化的办法! 从Win7.Win8.1开始,微软为我们带来完善的系统服务.任务计划程序,这些都一定程度提升了日常使用,实现了“半自动化.半智能化”交互体验.但是对于高级用 ...