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股 且一次 ...
随机推荐
- zabbix 监控openshift pod状态
需求: pod中的容器重启一次则报警通知 pod非Runing 状态则报警 pod中的容器非true状态则报警 三个需求其实是有点重叠的 pod重启期间pod肯定会有非Running状态,只要有重启报 ...
- 数据分析与挖掘 - R语言:贝叶斯分类算法(案例一)
一个简单的例子!环境:CentOS6.5Hadoop集群.Hive.R.RHive,具体安装及调试方法见博客内文档. 名词解释: 先验概率:由以往的数据分析得到的概率, 叫做先验概率. 后验概率:而在 ...
- MySQL数据类型--与MySQL零距离接触2-11MySQL自动编号
MySQL自动编号,确保数据的唯一性
- EF There is already an open DataReader associated with this Command
捕捉到 System.InvalidOperationException _HResult=-2146233079 _message=意外的连接状态.在使用包装提供程序时,请确保在已包装的 DbCon ...
- Asp.net Core认证和授权:Cookie认证
关于asp.net core 的文章,博客园已经有很多大牛写过了. 这里我只是记录下自己在学习中的点滴和一些不懂的地方 Cookie一般是用户网站授权,当用户访问需要授权(authorization) ...
- 如何用html把文本框外观格式设为只显示底部的横线
html把文本框外观格式设为只显示底部的横线 <style> input[type='text']{background:none;border:none;border-bottom:1p ...
- Eclipse集成Hibernate操作Sqlserver实例
Eclipse搭建Hibernate开发环境,使用的数据库是Sqlserver2008 1.需要成功安装Eclipse,如果没有安装可以上网查资料. 2.Eclipse安装成功后,点击Help--&g ...
- Nodejs中原生遍历文件夹
最近在听老师讲的node课程,有个关于把异步变为同步读取文件夹的知识点做一些笔记, 让迭代器逐个自执行.
- c3p0:Connections could not be acquired from the underlying database!解决方案
在利用ssh框架做网站的时候遇到了一个比较棘手的问题,一直连接不上数据库,问题描述如下: 各种百度然后说的最多的解决方案是: 1,驱动配置有误:2,数据库连接地址有误:3,密码或帐号有误: 4,数据库 ...
- idea如何整理代码格式
1.先CRTL + A来选中需要整理的代码块.当然CRTL + A代表选中一个文件的所有代码. 2.然后CRTL + ALT + L,对,就是要记住这个快捷键.