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 ...
随机推荐
- Html5使用history对象history.pushState()和history.replaceState()方法添加和修改浏览历史记录
根据网上参考自己做个笔记:参考网址:http://javascript.ruanyifeng.com/bom/history.html history.pushState() HTML5为histor ...
- 【codeforces】【比赛题解】#948 CF Round #470 (Div.2)
[A]Protect Sheep 题意: 一个\(R*C\)的牧场中有一些羊和一些狼,如果狼在羊旁边就会把羊吃掉. 可以在空地上放狗,狼不能通过有狗的地方,狼的行走是四联通的. 问是否能够保护所有的羊 ...
- SELinux 入门【转】
一.前言 安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统.SELinux 主要由美国国 ...
- centos7联网
一般centos安装(在虚拟机上安装)完成后需要自己配置服务,下面我就讲下如何配置 配置联网步骤 首先,打开虚拟机的两个服务,右击我的电脑-->管理--->找到服务-->右击启动 两 ...
- iconfont-矢量图标字体
二.矢量图标使用 1.进入:http://www.iconfont.cn/ 搜索你图标的关键字,然后将需要的图标字体加入购物车 加入购物车之后,添加到项目 2.点击查看在线连接,生成css代码,把代 ...
- (五)动态SQL
第一节:if条件 第二节:choose,when和otherwise条件 第三节:where条件 1.自动加上where: 2.如果where子句以and或者or开头,则自动删除第一个and或者or: ...
- class getConstructor newinstance
public static void main(String[] args) throws Exception{ /**获取String对象指定的构造方法(通过方法的参数类型,传递 参数的 Class ...
- HBase混布MapReduce集群学习记录
一.准备工作 1.1 部署环境 集群规模大概260多台,TSC10机型,机型参数如下: > 1个8核CPU(E5-2620v4) > 64G内存 > HBA,12*4T SATA,1 ...
- EFK收集Kubernetes应用日志
本节内容: EFK介绍 安装配置EFK 配置efk-rbac.yaml文件 配置 es-controller.yaml 配置 es-service.yaml 配置 fluentd-es-ds.yaml ...
- oracle数据库11g(11.2.0.1)安装报错:提示ins_ctx.mk编译错误。
https://blog.csdn.net/weixin_42967330/article/details/81668404