BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)
要求的和、最大值、最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n。
于是建虚树就可以了。具体DP见DP()函数,维护三个值sum[],mx[],mn[]。
sum[]要开longlong!。。
//108172kb 2564ms(又是Rank4...)
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 1000000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e6+5,M=N<<1,INF=5e8;
int n,Q,K,A[N],Enum,H[N],nxt[M],to[M],val[M],dep[N],tp[N],top,sk[N],dfn[N],Index,fa[N],son[N],sz[N],mn[N],mx[N],Min,Max;
LL Sum,sum[N];
bool tag[N];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline bool cmp_dfn(const int &a,const int &b){
return dfn[a]<dfn[b];
}
inline void Add_direct(int u,int v){
to[++Enum]=v, nxt[Enum]=H[u], val[Enum]=dep[v]-dep[u], H[u]=Enum;
}
inline void AddEdge(int u,int v){
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS1(int x)
{
int mx=0; sz[x]=1;
for(int v,i=H[x]; i; i=nxt[i])
if((v=to[i])!=fa[x])
{
fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v];
if(mx<sz[v]) mx=sz[v], son[x]=v;
}
}
void DFS2(int x,int _tp)
{
dfn[x]=++Index, tp[x]=_tp;
if(son[x])
{
DFS2(son[x],_tp);
for(int i=H[x]; i; i=nxt[i])
if(to[i]!=fa[x]&&to[i]!=son[x]) DFS2(to[i],to[i]);
}
}
int LCA(int u,int v)
{
while(tp[u]!=tp[v]) dep[tp[u]]>dep[tp[v]]?u=fa[tp[u]]:v=fa[tp[v]];
return dep[u]>dep[v]?v:u;
}
void Insert(int p)
{
if(top==1) {sk[++top]=p; return;}
int lca=LCA(sk[top],p);
// if(lca==sk[top]) {sk[++top]=p; return;}
while(dfn[sk[top-1]]>=dfn[lca]) Add_direct(sk[top],sk[top--]);
if(lca!=sk[top] && dfn[sk[top-1]]<dfn[lca]) Add_direct(lca,sk[top]), sk[top]=lca;
sk[++top]=p;
}
void DP(int x)
{
sum[x]=0;
if(tag[x]) mn[x]=0, mx[x]=0/*可以以此为一端点*/, sz[x]=1;
else mn[x]=INF, mx[x]=-INF, sz[x]=0;
for(int v,i=H[x]; i; i=nxt[i])
{
DP(v=to[i]);
Min=std::min(Min, mn[x]+mn[v]+val[i]), mn[x]=std::min(mn[x], mn[v]+val[i]);
Max=std::max(Max, mx[x]+mx[v]+val[i]), mx[x]=std::max(mx[x], mx[v]+val[i]);
Sum+=1ll*sz[x]*(sum[v]+val[i]*sz[v])+1ll*sz[v]*sum[x];//之前的此时会被统计sz[v]次,v子树被统计sz[x]次 //long long!
sum[x]+=sum[v]+val[i]*sz[v], sz[x]+=sz[v];
}
tag[x]=H[x]=0;
}
int main()
{
n=read();
for(int i=1; i<n; ++i) AddEdge(read(),read());
DFS1(1), DFS2(1,1), Enum=0, memset(H,0,sizeof H);// memset(sz,0,sizeof sz);
Q=read();
while(Q--)
{
K=read();
for(int i=1; i<=K; ++i) tag[A[i]=read()]=1;
std::sort(A+1,A+1+K,cmp_dfn);
sk[top=1]=1;
if(A[1]==1) for(int i=2; i<=K; ++i) Insert(A[i]);//以1为根,注意不要加1两次。。
else for(int i=1; i<=K; ++i) Insert(A[i]);
while(--top) Add_direct(sk[top],sk[top+1]);//!
Sum=0, Min=INF, Max=-INF, DP(1);
printf("%lld %d %d\n",Sum,Min,Max);
Enum=0;// for(int i=1; i<=K; ++i) H[A[i]]=0;
}
return 0;
}
BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)的更多相关文章
- bzoj 3611: [Heoi2014]大工程 虚树
题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...
- BZOJ 3611 [Heoi2014]大工程 ——虚树
虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...
- luogu P4103 [HEOI2014]大工程 虚树 + 树形 DP
Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通 ...
- 洛谷P4103 [HEOI2014]大工程(虚树 树形dp)
题意 链接 Sol 虚树. 首先建出虚树,然后直接树形dp就行了. 最大最小值直接维护子树内到该节点的最大值,然后合并两棵子树的时候更新一下答案. 任意两点的路径和可以考虑每条边两边的贡献,\(d[x ...
- bzoj 3611[Heoi2014]大工程 虚树+dp
题意: 给一棵树 每次选 k 个关键点,然后在它们两两之间 新建 C(k,2)条 新通道. 求: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少 分析:较常 ...
- bzoj 3611 [Heoi2014]大工程(虚树+DP)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 408 Solved: 190[Submit][Status] ...
- bzoj 3611(洛谷 4103) [Heoi2014]大工程——虚树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3611 https://www.luogu.org/problemnew/show/P4103 ...
- bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战
放波建虚树的模板. 大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于lca的都弹出去. 每次做完记得复原. 还有sort的时候一定要加cmp!!! bzoj 3611 #include&l ...
- bzoj 3611: [Heoi2014]大工程
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...
随机推荐
- [转]ROS(Robot Operating System)常用环境变量介绍
本文简单介绍ROS系统中常用的环境变量用途及设置方式.ROS系统环境中除了必须配置的环境变量以外,其他的也是十分有用,通过修改变量路径,可以设置ROS系统中log文件存放路径,单元测试结果存放路径等. ...
- 【codeforces】【比赛题解】#864 CF Round #436 (Div.2)
做出了4题,还不错,可惜还是掉rating……能保持在蓝名已经不错了. 题目跳转链接. [A]公平的游戏 题意: Petya和Vasya在玩游戏.他们有n张卡片(n是偶数).每张卡片上有一个整数. 游 ...
- WCF 数据契约(DataContract)
服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型. 一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务端和客户端之间传送,如下所 ...
- MySQL 四种链接
1.内联接 INNER JOIN(典型的联接运算,使用像 = 或 <> 之类的比较运算符).包括相等联接和自然联接. 内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行. ...
- 一、springcloud服务注册、发现、调用(consul/eureka)
1.Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全 ...
- vue系列之项目优化
webpack中的Code Splitting Code Splitting是什么以及为什么 在以前,为了减少HTTP请求,通常地,我们会把所有的代码都打包成一个单独的JS文件,但是,如果这个文件体积 ...
- IE手工导入证书
打开cer文件->欢迎使用证书导入向导->下一步->将所有的证书放入下列存储->受信任的根证书颁发机构->完成
- 淘宝开放平台TOP SDK调用对接淘宝或天猫
如果在淘宝/天猫上开了网店,用户自己也有一套自己的管理平台,这时可能会考虑和淘宝进行数据对接.这就需要考虑调用阿里提供的开发接口来推送和接收数据. 对接的方式有2种,一种是通过http接口,另外一种是 ...
- (三)HtmlUnit 实践
第一节: htmlunit 爬取百度云资源
- SQL SERVER2008 镜像全攻略
--在非域控环境中创建数据库镜像, 我们必须使用证书来创建数据库镜像. 大致的步骤包括: --在为数据库镜像配置的每个服务器实例上执行下列步骤: --在 master 数据库中,创建数据库主密钥. - ...