[HEOI2014]大工程 题解
发现可以直接建立虚树。
设 \(dp_{u,0/1/2}\) 表示第 \(u\) 个节点的子树内,所有选中节点到它的距离之和/选中节点中到它的最短距离/选中节点中到它的最长距离,\(as_{u,0/1/2}\) 则代表对于这个子树,题目所问问题的三个答案,\(i1,i2\) 分别为使 \(dp_{u,1/2}\) 取极值的 \(v\)。
则 \(dp\) 方程为:
\]
\]
\]
\]
\]
\]
时间复杂度 \(O(\sum k\log k)\)。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1000005;
int n,l,q,dfn[N],fa[N][21],p[N],a[N];
int m,r,t,k,h[N],nxt[N*2],to[N*2];
int d[N],nex[N*2],go[N*2],dep[N],b[N*2];
ll dp[3][N],as[3][N],c[N*2],sz[N];
int cmp(int x,int y){
return dfn[x]<dfn[y];
}void ad(int x,int y){
to[++m]=y;nxt[m]=h[x];h[x]=m;
}void add(int x,int y,int z){
go[++r]=y;c[r]=z;
nex[r]=d[x];d[x]=r;
}void dfs(int x,int f){
dep[x]=dep[f]+1;
fa[x][0]=f;dfn[x]=++l;
for(int i=0;i<20;i++)
fa[x][i+1]=fa[fa[x][i]][i];
for(int i=h[x];i;i=nxt[i])
if(f!=to[i]) dfs(to[i],x);
}int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;~i;i--)
if(dep[x]-dep[y]>=(1<<i))
x=fa[x][i];
if(x==y) return x;
for(int i=20;~i;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}int dis(int x,int y){
return dep[x]+dep[y]-2*dep[lca(x,y)];
}void dp_(int x,int f){
ll i1=0,i2=0;
as[1][x]=1e18;
if(p[x]==2) sz[x]=1;
else dp[1][x]=1e18;
for(int i=d[x];i;i=nex[i]){
int y=go[i];
if(y==f) continue;
dp_(y,x);sz[x]+=sz[y];
dp[0][x]+=c[i]*sz[y]+dp[0][y];
if(dp[1][x]>dp[1][y]+c[i])
dp[1][x]=dp[1][y]+c[i],i1=y;
if(dp[2][x]<dp[2][y]+c[i])
dp[2][x]=dp[2][y]+c[i],i2=y;
}if(p[x]==2) as[2][x]=dp[2][x];
for(int i=d[x];i;i=nex[i]){
int y=go[i];if(y==f) continue;
as[0][x]+=as[0][y]+(c[i]*sz[y]+dp[0][y])*(sz[x]-sz[y]);
as[1][x]=min(as[1][y],as[1][x]);
as[2][x]=max(as[2][y],as[2][x]);
if(i1!=y)
as[1][x]=min(as[1][x],dp[1][x]+dp[1][y]+c[i]);
if(i2!=y)
as[2][x]=max(as[2][x],dp[2][x]+dp[2][y]+c[i]);
}
}int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1,x,y;i<n;i++)
cin>>x>>y,ad(x,y),ad(y,x);
dfs(1,0);
cin>>q;while(q--){
cin>>k;
for(int i=1;i<=k;i++)
cin>>a[i],b[++t]=a[i],p[a[i]]=2;
sort(a+1,a+k+1,cmp);
for(int i=1;i<k;i++){
int x=lca(a[i],a[i+1]);
if(!p[x]) p[x]=1,b[++t]=x;
}sort(b+1,b+t+1,cmp);
for(int i=1;i<t;i++){
int lc=lca(b[i],b[i+1]);
add(lc,b[i+1],dep[b[i+1]]-dep[lc]);
add(b[i+1],lc,dep[b[i+1]]-dep[lc]);
}int rt=lca(b[1],b[2]);dp_(rt,0);
cout<<as[0][rt]<<" "<<as[1][rt]<<" "<<as[2][rt]<<"\n";
for(int i=1;i<=t;i++){
p[b[i]]=sz[b[i]]=d[b[i]]=0;
dp[0][b[i]]=dp[1][b[i]]=dp[2][b[i]]=0;
as[0][b[i]]=dp[1][b[i]]=as[2][b[i]]=0;
}for(int i=1;i<=r;i++)
nex[i]=go[i]=c[i]=0;
r=t=0;
}return 0;
}
[HEOI2014]大工程 题解的更多相关文章
- [BZOJ3611][Heoi2014]大工程
[BZOJ3611][Heoi2014]大工程 试题描述 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 ...
- 【LG4103】[HEOI2014]大工程
[LG4103][HEOI2014]大工程 题面 洛谷 题解 先建虚树,下面所有讨论均是在虚树上的. 对于第一问:直接统计所有树边对答案的贡献即可. 对于第\(2,3\)问:记\(f[x]\)表示在\ ...
- BZOJ2286 [Sdoi2011]消耗战 和 BZOJ3611 [Heoi2014]大工程
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6371 Solved: 2496[Submit][Statu ...
- 【BZOJ3611】[Heoi2014]大工程 欧拉序+ST表+单调栈
[BZOJ3611][Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶 ...
- [Bzoj3611][Heoi2014]大工程(虚树)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 2000 Solved: 837[Submit][Status ...
- bzoj 3611 [Heoi2014]大工程(虚树+DP)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 408 Solved: 190[Submit][Status] ...
- 3611: [Heoi2014]大工程
3611: [Heoi2014]大工程 链接 分析: 树形dp+虚树. 首先建立虚树,在虚树上dp. dp:sum[i]为i的子树中所有询问点之间的和.siz[i]为i的子树中有多少询问点,mn[i] ...
- P4103 [HEOI2014]大工程
题目 P4103 [HEOI2014]大工程 化简题目:在树上选定\(k\)个点,求两两路径和,最大的一组路径,最小的一组路径 做法 关键点不多,建个虚树跑一边就好了 \(sum_i\)为\(i\)子 ...
- [BZOJ3611][Heoi2014]大工程(虚树上DP)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 2464 Solved: 1104[Submit][Statu ...
- bzoj 3611: [Heoi2014]大工程 虚树
题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...
随机推荐
- IO介绍-下
中断 由外部设备引起的中断,称为外中断. 由内部错误引起的中断,称为内中断,或者是陷入.例如:非法指令,地址越界,电源故障等. 中断向量表 中断优先级 多中断源的处理方式 屏蔽中断 嵌套中断 根据 ...
- 在腾讯云 EMR 上使用 GooseFS 加速大数据计算服务
GooseFS 是腾讯云对象存储团队最新推出的高性能.高可用以及可弹性伸缩的分布式缓存系统,依靠对象存储(Cloud Object Storage,COS)作为数据湖存储底座的成本优势,为数据湖生态中 ...
- 【数据库】MongoDB服务启动失败的问题。
1.确保MongoDB所在文件夹拥有所有权限 2.确保打开CMD窗口是以管理员身份运行的 3.配置文件中的路径应该为完整路径,且不包含空格和特殊字符(不建议包含) systemLog: destina ...
- shell 将文件内容读取到 数组中
#!/bin/bash prod_file=/home/vmuser/linbo/kettleDemo/job/test/CA-20201224.csv test_file=/home/vmuser/ ...
- #渗透测试 kioptix level 2靶机通关教程及提权
声明! 文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关,切勿触碰法律底线,否则后果自负!!!! 工具链接:https://pan.quark.cn/s/530656ba55 ...
- IM通讯协议专题学习(七):手把手教你如何在NodeJS中从零使用Protobuf
1.前言 Protobuf是Google开源的一种混合语言数据标准,已被各种互联网项目大量使用. Protobuf最大的特点是数据格式拥有极高的压缩比,这在移动互联时代是极具价值的(因为移动网络流量到 ...
- UWP Shadow 阴影
参考文字: https://mtaulty.com/2016/08/10/windows-10-uwp-and-composition-light-and-shade/ <Grid Backgr ...
- MySQL 开发规范
建表规约 1.[强制]每张表必须设置一个主键ID,并且这个主键ID要自增(在满足需要的情况下尽量短),除非是分库分表 理解:由于InnoDB存储引擎决定了需要有一个主键,而且这个主键ID是自增的话可以 ...
- 一个奇葩的SQL题,够强大。
困惑描述: 现有一张图片表,表里一个sort字段,这个字段是不重复的.不连续的数字.大致结构如下 create table Imgs( `id` bigint(20) NOT NULL AUTO_IN ...
- Qml 中实现时间轴组件
[写在前面] 时间轴组件是现代用户界面中常见的元素,用于按时间顺序展示事件. 本文将介绍如何使用 Qml 实现一个灵活且可定制的时间轴组件,并探讨其设计思路和实现细节. [正文开始] 效果图 组件概述 ...