P4381 [IOI2008]Island(基环树+单调队列优化dp)
题意:求图中所有基环树的直径和
我们对每棵基环树分别计算答案。
首先我们先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)的更多相关文章
- BZOJ1791 [Ioi2008]Island 岛屿[基环树+单调队列优化DP]
基环树直径裸题. 首先基环树直径只可能有两种形式:每棵基环树中的环上挂着的树的直径,或者是挂在环上的两个树的最大深度根之间的距离之和. 所以,先对每个连通块跑一遍,把环上的点找出来,然后对环上每个点跑 ...
- bzoj 1791: [Ioi2008]Island 岛屿【基环树+单调队列优化dp】
我太菜了居然调了一上午-- 这个题就是要求基环树森林的基环树直径和 大概步骤就是找环->dp找每个环点最远能到达距离作为点权->复制一倍环,单调队列dp 找环是可以拓扑的,但是利用性质有更 ...
- BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP
题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...
- BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP
BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...
- 【bzoj3831】[Poi2014]Little Bird 单调队列优化dp
原文地址:http://www.cnblogs.com/GXZlegend/p/6826475.html 题目描述 In the Byteotian Line Forest there are t ...
- Codeforces 1304F1/F2 Animal Observation(单调队列优化 dp)
easy 题目链接 & hard 题目链接 给出一张 \(n \times m\) 的矩阵,每个格子上面有一个数,你要在每行选出一个点 \((i,t)\),并覆盖左上角为 \((i,t)\), ...
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- 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 ...
- hdu3401:单调队列优化dp
第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...
随机推荐
- php 实现php代码的加密解密
php 代码加密类,大家可以根据自己的需求进行修改,原类如下,是对之前的加密解密类的有一次修改,希望能分享给大家.本次在ubuntu下测试没有问题,与之前的版本的区别在于,这次的版本更加的通用性. & ...
- Locust性能测试
https://www.cnblogs.com/yoyoketang/p/9638151.html https://www.cnblogs.com/yoyoketang/p/9642242.html ...
- 胸片和CT断层图像是怎么来的?
本文作者系医科大学青年教师,关注公众号"计算机视觉life"菜单栏回复"医学" 进群交流 如何得到CT断层图像? 相信小伙伴体检的时候都拍过胸片,假如哪个不幸的 ...
- java-Unicode与中文的转换
package utils; import org.apache.commons.lang3.StringUtils; public class UnicodeUtils { public stati ...
- 使用dynamic引发的异常:无法对 null 引用执行运行时绑定
今天上午运营反映有商户的账单没有生成. 查看日志,在批量生成账单服务执行过程中,因为如下异常而中断了: 跑批异常 Microsoft.CSharp.RuntimeBinder.RuntimeBinde ...
- Nginx.代理MySQL
Nginx.代理MySQL 1. Nginx在安装的时候,需要加上一个参数:--with-stream 即Nginx安装指令为:./configure --prefix=/u01/app/nginx ...
- 搭建私有仓库Harbor
搭建Harbor企业级docker仓库 搭建Harbor企业级docker仓库 一.Harbor简介 1.Harbor介绍 Harbor是一个用于存储和分发Docker镜像的企业级Registry ...
- Install the mongdb
#!/bin/bash#Function: Install the mongdb#Author: WangDonghui#Date: 20180124 #Installing mongdbecho & ...
- sv命令空间 packge
SV中的module,interface,program,checker,都提供declaration空间,内部定义都local当前的那个scope,相互之间的building block不影响,不识 ...
- sitecore中的两种编辑工具介绍
在Sitecore中,有两种编辑工具,您可以在其中创建和编辑网站上的内容: 内容编辑器 - 专为熟悉Sitecore及其包含的功能的经验丰富的内容作者而设计的应用程序. 体验编辑器 - 一种直观的编辑 ...