#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define M 2000009
#define inf 0x7ffffff
#define ll long long
using namespace std;
int n,head[M],next[M],u[M],cnt,head1[M],next1[M],u1[M],fa[M][],deep[M],m,dfn[M],T,v[M];
int h[M],st[M],mn[M],mx[M],size[M],mx1,mi1,v1[M];
ll cn1,sum[M];
void jia(int a1,int a2)
{
cnt++;
next[cnt]=head[a1];
head[a1]=cnt;
u[cnt]=a2;
return;
}
void jia2(int a1,int a2)
{
if(a1==a2)
return;
cnt++;
next1[cnt]=head1[a1];
head1[a1]=cnt;
u1[cnt]=a2;
v1[cnt]=deep[a2]-deep[a1];
return;
}
bool cmp(int a1,int a2)
{
return dfn[a1]<dfn[a2];
}
void dfs(int a1)
{
dfn[a1]=++T;
for(int i=;(<<i)<=deep[a1];i++)
fa[a1][i]=fa[fa[a1][i-]][i-];
for(int i=head[a1];i;i=next[i])
if(fa[a1][]!=u[i])
{
deep[u[i]]=deep[a1]+;
fa[u[i]][]=a1;
dfs(u[i]);
}
return;
}
int lca(int a1,int a2)
{
if(deep[a1]<deep[a2])
swap(a1,a2);
int a3=deep[a1]-deep[a2];
for(int i=;i<=;i++)
if(a3&(<<i))
a1=fa[a1][i];
for(int i=;i>=;i--)
if(fa[a1][i]!=fa[a2][i])
{
a1=fa[a1][i];
a2=fa[a2][i];
}
if(a1==a2)
return a1;
return fa[a1][];
}
void dp(int x){
sum[x]=;
mx[x]=v[x]?:-inf;
mn[x]=v[x]?:inf;
size[x]=v[x];
for(int i=head1[x];i;i=next1[i]){
int v=u1[i];
dp(v);
cn1+=(sum[x]+size[x]*v1[i])*size[v]+size[x]*sum[v];
size[x]+=size[v];
sum[x]+=sum[v]+(ll)size[v]*v1[i];
mi1=min(mi1,mn[v]+mn[x]+v1[i]);
mx1=max(mx1,mx[v]+mx[x]+v1[i]);
mn[x]=min(mn[x],mn[v]+v1[i]);
mx[x]=max(mx[x],mx[v]+v1[i]);
}
head1[x]=;
}
void solve(){
cnt=cn1=;mi1=inf;mx1=-inf;
int K;
scanf("%d",&K);
for(int i=;i<=K;i++) scanf("%d",&h[i]),v[h[i]]=;
sort(h+,h+K+,cmp);int top=;st[]=;
for(int i=;i<=K;i++){
int now=h[i],f=lca(st[top],now);
if(dfn[f]==dfn[st[top]]) st[++top]=now;
else{
while(top){
int q=st[top-];
if(dfn[q]>dfn[f]) jia2(st[top-],st[top]),top--;
else if(dfn[q]==dfn[f]){
jia2(q,st[top]);top--;break;
}
else {
jia2(f,st[top]);st[top]=f;break;
}
}
if(st[top]!=now) st[++top]=now;
}
}
while(--top)jia2(st[top],st[top+]);
dp();
printf("%lld ",cn1);
printf("%d %d\n",mi1,mx1);
for(int i=;i<=K;i++) v[h[i]]=;
}
int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
int a1,a2;
scanf("%d%d",&a1,&a2);
jia(a1,a2);
jia(a2,a1);
}
dfs();
scanf("%d",&m);
for(int i=;i<=m;i++)
solve();
return ;
}

虚树,树形DP

bzoj 3611: [Heoi2014]大工程的更多相关文章

  1. bzoj 3611 [Heoi2014]大工程(虚树+DP)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 408  Solved: 190[Submit][Status] ...

  2. bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战

    放波建虚树的模板. 大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于lca的都弹出去. 每次做完记得复原. 还有sort的时候一定要加cmp!!! bzoj 3611 #include&l ...

  3. bzoj 3611: [Heoi2014]大工程 虚树

    题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...

  4. bzoj 3611[Heoi2014]大工程 虚树+dp

    题意: 给一棵树 每次选 k 个关键点,然后在它们两两之间 新建 C(k,2)条 新通道. 求: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少 分析:较常 ...

  5. BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)

    题目链接 要求的和.最大值.最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n. 于是建虚树就可以了.具体DP见DP()函数,维护三个值sum[],mx[],mn[]. sum[]要开 ...

  6. BZOJ 3611 [Heoi2014]大工程 ——虚树

    虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...

  7. 3611: [Heoi2014]大工程

    3611: [Heoi2014]大工程 链接 分析: 树形dp+虚树. 首先建立虚树,在虚树上dp. dp:sum[i]为i的子树中所有询问点之间的和.siz[i]为i的子树中有多少询问点,mn[i] ...

  8. BZOJ2286 [Sdoi2011]消耗战 和 BZOJ3611 [Heoi2014]大工程

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6371  Solved: 2496[Submit][Statu ...

  9. [Bzoj3611][Heoi2014]大工程(虚树)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 2000  Solved: 837[Submit][Status ...

随机推荐

  1. [翻译]lithium 快速上手(QuickStart)

      ​ 快速入门 经典博客教程 很感谢你尝试Li3!这一部分栏目为那些想了解这个框架可以做什么的php用户所设计.像这样深入代码是一种很好的方式去体会快速应用开发(Rapid Application ...

  2. IOS的H5页面滑动不流畅的问题:

    IOS的H5页面滑动不流畅的问题: -webkit-overflow-scrolling : touch; 需要滑动的是哪块区域,就在哪里加上这段代码就OK

  3. UVA 11384 正序数排列

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. Jquery Json 下拉联动

    #region dataTable转换成Json格式 /// <summary> /// dataTable转换成Json格式 /// </summary> /// <p ...

  5. 移动端页面 弹出框滚动,底部body锁定,不滚动 / 微信网页禁止回弹效果

    需求:页面有弹出层菜单,当弹出层菜单超出屏幕可视区域时,不能滚动.加上滚动后,底部body的滚动事件如何禁止,加上了overflow:hidden;还是不可用. 如下图:地区弹出框可以滚动,而底部的b ...

  6. ubuntu服务管理

    uRedhat 提供了chkconfig这个命令来管理系统在不同运行级别下的服务开启/关闭: chkconfig ServiceName on/off 并可以用chkconfig --list(两个杠 ...

  7. Log4net(1):配置的简单说明

    基础代码下载地址:https://github.com/zhangsai521314/StudyLog4net 1:按日期分隔日志 <configSections> <section ...

  8. 使用时间戳和sequence生成主键的function

    create or replace function fn_getKeyreturn varchar2is  k varchar2(30);begin  select to_char(sysdate, ...

  9. 24. Swap Nodes in Pairs

    24. Swap Nodes in Pairs Given a linked list, swap every two adjacent nodes and return its head. For ...

  10. poj2965 The Pilots Brothers' refrigerator

    题目链接:http://poj.org/problem?id=2965 分析:1.这道题和之前做的poj1753题目差不多,常规思路也差不多,但是除了要输出最少步数外,还要输出路径.做这道题的时候在怎 ...