P4381 [IOI2008]Island

题意:求图中所有基环树的直径和

我们对每棵基环树分别计算答案。

首先我们先bfs找环(dfs易爆栈)

蓝后我们处理直径

直径不在环上,就在环上某点的子树上

我们对于环上每个点的子树,跑一边dp求直径即可,顺带处理子树的最深深度(环上点到子树某个叶节点的最长距离)$dis[x]$

在dfs求直径时顺带求直径的最大值(可能是整棵基环树的直径)

蓝后我们在环上跑一遍dp。

我们先破环成链(就是把长度为$n$的环转换成长$2n+1$的链)

偷个图

我们记链上前$i$个点之间边的总长(前缀和)$sum[i]$

枚举$j(1<=j<i,i-j<n)$,得

$ans=max(ans,dis[i]+sum[i]-sum[j]+dis[j])$,表示子树$i$的直径$+$子树$j$的直径+$i,j$在环上之间的距离

我们分离一下上面的式子:$(dis[i]+sum[i])+(dis[j]-sum[j])$

这不是可以单调队列维护

于是再搞个单调队列优化dp就完事辣

bzoj还是爆栈了TAT

#include<iostream>
#include<cstdio>
#include<cstring>
#define rint register int
using namespace std;
typedef long long ll;
inline ll Max(ll a,ll b){return a>b?a:b;}
void read(int &x){
char c=getchar();x=;
while(c<''||c>'') c=getchar();
while(''<=c&&c<='') x=x*+(c^),c=getchar();
}
#define N 1000005
int n,ri[N],d[N],is[N],To[N],W[N],fa[N],len,L,R,h[N];
ll ans,re,sum[N],dis[N]; bool vis[N];
int cnt,hd[N],nxt[N<<],ed[N],poi[N<<],val[N<<];
inline void adde(int x,int y,int v){
nxt[ed[x]]=++cnt, hd[x]=hd[x]?hd[x]:cnt;
ed[x]=cnt, poi[cnt]=y, val[cnt]=v;
}
void bfs(int x){//找环
rint p; vis[x]=;len=;
while(){
p=To[x];
if(vis[p]){
ri[++len]=p,d[len]=W[p],is[p]=;
for(;x!=p;x=fa[x])
ri[++len]=x,d[len]=W[x],is[x]=;
break;
}vis[p]=;fa[p]=x;x=p;
}
}
void dfs(int x,int Fa){//dfs求子树直径
vis[x]=;
for(int i=hd[x];i;i=nxt[i]){
int to=poi[i];
if(is[to]||to==Fa) continue;
dfs(to,x); re=Max(re,dis[x]+dis[to]+(ll)val[i]);
dis[x]=Max(dis[x],dis[to]+val[i]);
}
}
inline int Id(int x){return (x-)%len+;}
inline ll F(int x){return dis[ri[Id(x)]]-sum[x];}
void solve(){//单调队列优化,环上dp
L=;R=;
for(rint i=;i<=len*;++i){
sum[i]=sum[i-]+d[Id(i)];
while(L<=R&&i-h[L]>=len) ++L;
if(L<=R) re=Max(re,F(h[L])+dis[ri[Id(i)]]+sum[i]);
while(L<=R&&F(h[R])<=F(i)) --R;
h[++R]=i;
}
}
int main(){
read(n);
for(rint i=;i<=n;++i){
read(To[i]); read(W[i]);
adde(i,To[i],W[i]); adde(To[i],i,W[i]);
}
for(rint i=;i<=n;++i){
if(vis[i]) continue;
re=; bfs(i);
for(rint j=;j<=len;++j) dfs(ri[j],);
solve(); ans+=re;//每棵树分别处理
}printf("%lld",ans);
return ;
}

P4381 [IOI2008]Island(基环树+单调队列优化dp)的更多相关文章

  1. BZOJ1791 [Ioi2008]Island 岛屿[基环树+单调队列优化DP]

    基环树直径裸题. 首先基环树直径只可能有两种形式:每棵基环树中的环上挂着的树的直径,或者是挂在环上的两个树的最大深度根之间的距离之和. 所以,先对每个连通块跑一遍,把环上的点找出来,然后对环上每个点跑 ...

  2. bzoj 1791: [Ioi2008]Island 岛屿【基环树+单调队列优化dp】

    我太菜了居然调了一上午-- 这个题就是要求基环树森林的基环树直径和 大概步骤就是找环->dp找每个环点最远能到达距离作为点权->复制一倍环,单调队列dp 找环是可以拓扑的,但是利用性质有更 ...

  3. BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP

    题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...

  4. BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP

    BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...

  5. 【bzoj3831】[Poi2014]Little Bird 单调队列优化dp

    原文地址:http://www.cnblogs.com/GXZlegend/p/6826475.html 题目描述 In the Byteotian Line Forest there are   t ...

  6. Codeforces 1304F1/F2 Animal Observation(单调队列优化 dp)

    easy 题目链接 & hard 题目链接 给出一张 \(n \times m\) 的矩阵,每个格子上面有一个数,你要在每行选出一个点 \((i,t)\),并覆盖左上角为 \((i,t)\), ...

  7. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  8. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  9. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

随机推荐

  1. sklearn.svm.LinearSVC文档学习

    https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC 1 ...

  2. zabbix 监控 redis

    redis  可以直接使用zabbix官方的模板 模板地址: https://github.com/blacked/zbx_redis_template redis 主机通过脚本把数据推送到zabbi ...

  3. wue父子通信和动态路由 还有点击事件直接赋值传参数

    这种直接在后面赋值 传值

  4. script命令录屏

    关于linux上的操作,我们的确可以使用'history'命令来显示出来操作记录,但是有些时候,我们不仅仅需要知道做了什么,还需要知道操作的时候,产生了什么效果,这个时候‘history’命令就显示无 ...

  5. matplotlib画的图保存为emf格式

    在用matplotlib保存图片时,发现不能直接保存为emf格式.百度有人说要先另存为svg格式,再使用INKSCAPE软件转换成emf格式.我试了一下,发现还是不行,后来,发现先用matplotli ...

  6. System.ArgumentException: 目标数组的长度不够。请检查 destIndex 和长度以及数组的下限

    扫码支付接口将要上线,近几天在优化系统性能.昨天把日志Helper类的日志记录改成了使用Queue<T>对象来实现异步处理.做了单元测试,并模拟多线程来测试后,发现正常.今天将站点部署到准 ...

  7. gitlab4.0备份还原

    一,备份 备份默认路径查看: gitlab/config/gitlab.yml 中的backup: 默认tmp/backups ====>这个是gitlab/tmp/backups/  可不是系 ...

  8. Linux 配置yum源.

    Linux 配置yum源. 环境:虚拟机中安装了RedHat ,在进行安装mariadb的时候,出现如下错误.是因为yum源的问题,需要进行配置yum源.本教程是配置本地yum源. [root@loc ...

  9. Xshell连接不上虚拟机提示ssh服务器拒绝了密码,请再试一次

    1. 设置ubuntu的管理员root的密码 hughes@hughes-virtual:~$ sudo passwd (供xshell连接时使用) 2. 确保源文件和系统已更新 hughes@hug ...

  10. Java IO留存查看

    IO也可以写作为 "i/O" ,也可以理解为In和Out,即输入与输出.所以,IO体系的基本功能就是: 读和写. IO流作用:读写设备上的东西,硬盘文件.内存.键盘.网络... 根 ...