bzoj1791[IOI2008]Island岛屿(基环树+DP)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1791
题目大意:给你一棵n条边的基环树森林,要你求出所有基环树/树的直径之和。n<=1e6
题解:基环树DP写的很少……
树的直径不用解释了,就是NOIP2018D1T3的20分做法,基环树直径,我们可以yy一下然后就能发现答案是2种:1、把环剖去以后其余的子树的直径。2、环上的一部分+选中的2点中各自的最长链。
第一种可以直接dfs求解,对于第二种……我们可以摒弃垃圾的dfs两遍求树的直径的做法,改成DP形式的求树的直径。然后找到一个环时,记录环上的点最深的深度,然后可以把这个环扩展,记录l,r指针,扫描,随便搞一下就能求得答案。
所以本蒟蒻想到的具体做法就是:先topsort一下,把环给找出来,边topsort边DP,然后遇到环再dfs就OK了
不说废话看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+;
int n,cnt,tim,hd[N],v[N],nxt[N],w[N],c[N],du[N],vis[N],q[N];
ll ans,d[N],f[N],a[N],b[N];
void add(int x,int y,int z){v[++cnt]=y,nxt[cnt]=hd[x],hd[x]=cnt,w[cnt]=z;}
void dfs(int u,int k)
{
c[u]=k;
for(int i=hd[u];i;i=nxt[i])if(!c[v[i]])dfs(v[i],k);
}
void topsort()
{
int qs=,qe=;
for(int i=;i<=n;i++)if(du[i]==)q[qe++]=i;
while(qs<qe)
{
int u=q[qs++];
for(int i=hd[u];i;i=nxt[i])
if(du[v[i]]>)
{
du[v[i]]--;
d[c[u]]=max(d[c[u]],f[u]+f[v[i]]+w[i]);
f[v[i]]=max(f[v[i]],f[u]+w[i]);
if(du[v[i]]==)q[qe++]=v[i];
}
}
}
void dp(int x,int tp)
{
int m=,y=x,i;
do{
a[++m]=f[y];
du[y]=;
for(i=hd[y];i;i=nxt[i])
if(du[v[i]]>){b[m+]=b[m]+w[i];y=v[i];break;}
}while(i);
if(m==)
{
int len=;
for(int i=hd[y];i;i=nxt[i])if(v[i]==x)len=max(len,w[i]);
d[tp]=max(d[tp],f[x]+f[y]+len);
return;
}
for(int i=hd[y];i;i=nxt[i])if(v[i]==x){b[m+]=b[m]+w[i];break;}
for(int i=;i<=m;i++)a[m+i]=a[i],b[m+i]=b[m+]+b[i];
int l=,r=;
l=r=q[]=;
for(int i=;i<*m;i++)
{
while(l<=r&&i-q[l]>=m)l++;
d[tp]=max(d[tp],b[i]-b[q[l]]+a[i]+a[q[l]]);
while(l<=r&&a[q[r]]+b[i]-b[q[r]]<=a[i])r--;
q[++r]=i;
}
}
int main()
{
scanf("%d",&n);
for(int i=,x,y;i<=n;i++)scanf("%d%d",&x,&y),add(i,x,y),add(x,i,y),du[x]++,du[i]++;
for(int i=;i<=n;i++)if(!c[i])dfs(i,++tim);
topsort();
for(int i=;i<=n;i++)
if(du[i]>&&!vis[c[i]])vis[c[i]]=,dp(i,c[i]),ans+=d[c[i]];
printf("%lld",ans);
}
bzoj1791[IOI2008]Island岛屿(基环树+DP)的更多相关文章
- [bzoj1791][ioi2008]Island 岛屿(基环树、树的直径)
[bzoj1791][ioi2008]Island 岛屿(基环树.树的直径) bzoj luogu 题意可能会很绕 一句话:基环树的直径. 求直径: 对于环上每一个点记录其向它的子树最长路径为$dp_ ...
- BZOJ1791 [Ioi2008]Island 岛屿[基环树+单调队列优化DP]
基环树直径裸题. 首先基环树直径只可能有两种形式:每棵基环树中的环上挂着的树的直径,或者是挂在环上的两个树的最大深度根之间的距离之和. 所以,先对每个连通块跑一遍,把环上的点找出来,然后对环上每个点跑 ...
- [BZOJ1791][IOI2008]Island岛屿(环套树DP)
同NOI2013快餐店(NOI出原题?),下面代码由于BZOJ栈空间过小会RE. 大致是对每个连通块找到环,在所有内向树做一遍DP,再在环上做两遍前缀和优化的DP. #include<cstdi ...
- BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP
题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...
- BZOJ 1791: [IOI2008]Island 岛屿 - 基环树
传送门 题解 题意 = 找出无向基环树森林的每颗基环树的直径. 我们首先需要找到每颗基环树的环, 但是因为是无向图,用tarjan找环, 加个手工栈, 我也是看了dalao的博客才知道tarjan找无 ...
- BZOJ1791: [Ioi2008]Island 岛屿
BZOJ1791: [Ioi2008]Island 岛屿 Description 你将要游览一个有N个岛屿的公园. 从每一个岛i出发,只建造一座桥. 桥的长度以Li表示. 公园内总共有N座桥. 尽管每 ...
- bzoj1791: [Ioi2008]Island 岛屿 单调队列优化dp
1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1826 Solved: 405[Submit][S ...
- bzoj千题计划114:bzoj1791: [Ioi2008]Island 岛屿
http://www.lydsy.com/JudgeOnline/problem.php?id=1791 就是求所有基环树的直径之和 加手工栈 #include<cstdio> #incl ...
- P4381 [IOI2008]Island(基环树+单调队列优化dp)
P4381 [IOI2008]Island 题意:求图中所有基环树的直径和 我们对每棵基环树分别计算答案. 首先我们先bfs找环(dfs易爆栈) 蓝后我们处理直径 直径不在环上,就在环上某点的子树上 ...
随机推荐
- groovy安装 ideal
参考:https://blog.csdn.net/newbie_907486852/article/details/80879745 (1) 首先下载groovy: https://gradle.or ...
- SSM框架整合系列——第一步
环境: JDK8 idea2018.2 maven3.5 spring和springMVC是天然集成,所以只需要解决mybatis和spring的整合问题,重点整合mybatis和spring的两个东 ...
- sql查询表中重复数据个数
select train_code,count(1) from tb_ask_trainbodyroadtrain group by train_code having count(1) >1
- 在 Web 页面中使用离线地图
1. 所需工具&插件: 1. MapDownloader (提取码: spx6) 2. GISMysqlToLocalFile (提取码: vus6) 3. Leaflet 2. 操作: 1. ...
- 原子变量与CAS算法(二)
一.锁机制存在的问题 (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2)一个线程持有锁会导致其它所有需要此锁的线程挂起. (3)如果一个优先级高的线程等待一个 ...
- 人工智能将继续壮大,两会委员建议增加“AI+教育”支持板块
导读 今年上海两会期间,上海市政协委员.上海交通大学机械与动力工程学院教授范秀敏提交提案,建议政府在推进上海人工智能专项建设中,增加“AI+教育”专项支持板块,并鼓励集聚发展AI产业的各个区,在人工智 ...
- Node.js机制及原理理解初步【转】
一.node.js优缺点 node.js是单线程. 好处就是 1)简单 2)高性能,避免了频繁的线程切换开销 3)占用资源小,因为是单线程,在大负荷情况下,对内存占用仍然很低 3)线程安全,没有加锁. ...
- 基于虚拟主机的HAProxy配置实战
本实例是如上图所示 主要实现的功能如下: 当客户访问www.tb.com/tb.com的时候HAProxy将网站提交到电商服务器集群当访问bbs.tb.com的时候,将访问请求调度到论坛集群,实现论坛 ...
- CF558E-A Simple Task-线段树+计数排序
计数排序的原理,只要知道了有几个数比i小,就可以知道i的位置 这道题只有26个字母,搞26颗线段树,然后区间更新 #include <cstdio> #include <cstrin ...
- Bomb Game HDU - 3622(二分最小值最大化)
题意: 就是给出n对坐标,每对只能选一个,以选出来的点为圆心,半径自定义,画圆,而这些圆不能覆盖,求半径最小的圆的最大值 解析: 看到最x值最x化,那二分变为判定性问题,然后...然后我就没想到... ...