[Bzoj3611]大工程(虚树+DP)
Description
Solution
在虚树上跑DP即可
关于虚树的建立,是维护一个最右链的过程
关键代码如下:
sort(A+1,A+k+1,cmp);//按dfs序排序
s[top=1]=1;//栈维护最右链
for(int i=1;i<=k;++i){
int t=A[i],f=0;
while(top){
f=LCA(A[i],s[top]);
if(top>1&&dep[f]<dep[s[top-1]])
Link(s[top-1],s[top]),top--;
else if(dep[f]<dep[s[top]]){Link(f,s[top--]);break;}
else break;
}
if(s[top]!=f) s[++top]=f;
s[++top]=t;
}
while(--top) Link(s[top],s[top+1]);
Code
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define Inf 0x7fffffff
#define ll long long
#define N 1000010
using namespace std;
struct info{int to,nex,w;}e[N*4];
int n,tot,head[N],dfn[N],fa[N][20],_log,dep[N],A[N],mn[N],mx[N];
bool b[N];
ll Ans1,Ans2,f[N],size[N],sum;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void Link(int u,int v){
if(u==v) return;
e[++tot].to=v;e[tot].nex=head[u];head[u]=tot;e[tot].w=dep[v]-dep[u];
}
void dfs(int u,int pre){
dfn[u]=++tot;
for(int i=1;i<=_log;++i)
fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v==pre) continue;
dep[v]=dep[u]+1;
fa[v][0]=u;
dfs(v,u);
}
head[u]=0;
}
int LCA(int u,int v){
if(dep[u]>dep[v]) swap(u,v);
int d=dep[v]-dep[u];
for(int i=0;i<=_log;++i)
if(d&(1<<i)) v=fa[v][i];
if(u==v) return v;
for(int i=_log;i>=0;--i)
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];
v=fa[v][i];
}
return fa[u][0];
}
bool cmp(int a,int b){return dfn[a]<dfn[b];}
int s[N],top;
void bulid(){
int k=read();for(int i=1;i<=k;++i) b[A[i]=read()]=1;
sort(A+1,A+k+1,cmp);
s[top=1]=1;
for(int i=1;i<=k;++i){
int t=A[i],f=0;
while(top){
f=LCA(A[i],s[top]);
if(top>1&&dep[f]<dep[s[top-1]])
Link(s[top-1],s[top]),top--;
else if(dep[f]<dep[s[top]]){Link(f,s[top--]);break;}
else break;
}
if(s[top]!=f) s[++top]=f;
s[++top]=t;
}
while(--top) Link(s[top],s[top+1]);
}
void dp(int u){
size[u]=b[u];
f[u]=0;
mn[u]=b[u]?0:Inf;
mx[u]=b[u]?0:-Inf;
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
dp(v);
sum+=(f[u]+size[u]*e[i].w)*size[v]+f[v]*size[u];
size[u]+=size[v];
f[u]+=f[v]+e[i].w*size[v];
Ans1=min(Ans1,(ll)mn[u]+mn[v]+e[i].w);
Ans2=max(Ans2,(ll)mx[u]+mx[v]+e[i].w);
mn[u]=min(mn[u],mn[v]+e[i].w);
mx[u]=max(mx[u],mx[v]+e[i].w);
}
head[u]=0;
}
int main(){
n=read();_log=log(n)/log(2);
for(int i=1;i<n;++i){
int u=read(),v=read();
Link(u,v);Link(v,u);
}
tot=0;dfs(1,0);
int q=read();
while(q--){
bulid();
Ans1=1e16,Ans2=-1e16,sum=0;
dp(1);
printf("%lld %lld %lld\n",sum,Ans1,Ans2);
memset(b,0,sizeof(b));
}
return 0;
}
[Bzoj3611]大工程(虚树+DP)的更多相关文章
- [HEOI2014][bzoj3611] 大工程 [虚树+dp]
题面: 传送门 思路: 又是一道虚树入门级的题目,但是这道题的实际难点在于dp 首先,这道题是可以点分治做的,而且因为6s时限随便浪,所以写点分治也不是不可以 但是,dp因为$O\left(n\rig ...
- bzoj 3611[Heoi2014]大工程 虚树+dp
题意: 给一棵树 每次选 k 个关键点,然后在它们两两之间 新建 C(k,2)条 新通道. 求: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少 分析:较常 ...
- luogu P4103 [HEOI2014]大工程 虚树 + 树形 DP
Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通 ...
- 洛谷P4103 [HEOI2014]大工程(虚树 树形dp)
题意 链接 Sol 虚树. 首先建出虚树,然后直接树形dp就行了. 最大最小值直接维护子树内到该节点的最大值,然后合并两棵子树的时候更新一下答案. 任意两点的路径和可以考虑每条边两边的贡献,\(d[x ...
- BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)
题目链接 要求的和.最大值.最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n. 于是建虚树就可以了.具体DP见DP()函数,维护三个值sum[],mx[],mn[]. sum[]要开 ...
- bzoj 3611: [Heoi2014]大工程 虚树
题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...
- 【HEOI2014】大工程<虚树>
虚树 我们每天都用心思索着,这究竟是为了什么呢?我想我也不知道,只是觉得如果人不思考问题就很无聊. 我觉得虚树不是什么数据结构,就是一种技巧或者工具.它能把树中\(k\)个关键点以\(O(klogk) ...
- bzoj 3611(洛谷 4103) [Heoi2014]大工程——虚树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3611 https://www.luogu.org/problemnew/show/P4103 ...
- BZOJ 3611 [Heoi2014]大工程 ——虚树
虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...
- bzoj 3572世界树 虚树+dp
题目大意: 给一棵树,每次给出一些关键点,对于树上每个点,被离它最近的关键点(距离相同被标号最小的)控制 求每个关键点控制多少个点 分析: 虚树+dp dp过程如下: 第一次dp,递归求出每个点子树中 ...
随机推荐
- 5.jQuery&Ajax
1.jQuery 什么是 jQuery ? jQuery是一个JavaScript函数库.jQuery是一个轻量级的"写的少,做的多"的JavaScript库.包含以下功能: HT ...
- 【Microsoft Azure学习之旅】测试消息队列(Service Bus Queue)是否会丢消息
组里最近遇到一个问题,微软的Azure Service Bus Queue是否可靠?是否会出现丢失消息的情况? 具体缘由如下, 由于开发的产品是SaaS产品,为防止消息丢失,跨Module消息传递使用 ...
- Struts2_用ModelDriven接收参数
通过实现 ModelDriven 接口来接收请求参数,这种方法用的比较少,一般还是用前两种. 请求: <a href="user/user!add?name=xiaoer&ag ...
- strdup和strndup函数
首先说明一下:这两个函数不建议使用,原因是返回内存地址把释放权交给别的变量,容易忘记释放. 一.strdup函数 函数原型 头文件:#include <string.h> char *st ...
- 吴超hadoop7天视频教程全集
吴超hadoop7天视频教程全集 一.初级班全套视频 1.linux使用(3节) 2.伪分布模式安装hadoop(2节) 3.HDFS的体系结构和操作(2节) 4.HDFS的java操作方式(4节) ...
- HTML入门2—HTML常用标签
HTML常用标签练习 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...
- 字符串查找算法的改进-hash查找算法
字符串查找即为特征查找: 特征即位hash: 1.将待查找的字符串hash: 2.在容器字符串中找头字符匹配的字符串,并进行hash: 3.比较hash的结果:相同即位匹配: hash算法的设计为其中 ...
- ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id
远程删除key ssh-keygen -f "~/.ssh/known_hosts" -R 192.168.0.34 如果还是不可以,通过 ssh-keygen 重新生成key
- CentOS6.5手动升级gcc4.8.2
一.简易安装 操作环境 CentOS6.5 64bit,原版本4.4.7,不能支持C++11的特性~,希望升级到4.8.2 不能通过yum的方法升级,需要自己手动下载安装包并编译 本文记录了在Cent ...
- Java中JSON字符串与java对象的互换实例详解
这篇文章主要介绍了在java中,JSON字符串与java对象的相互转换实例详解,非常不错,具有参考借鉴价值,需要的朋友可以参考下 在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JS ...