Description

国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。 
我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。 
在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a,b 的最短路径。
 现在国家有很多个计划,每个计划都是这样,我们选中了 k 个点,然后在它们两两之间 新建 C(k,2)条 新通道。
现在对于每个计划,我们想知道:
 1.这些新通道的代价和
 2.这些新通道中代价最小的是多少 
3.这些新通道中代价最大的是多少
 

Input

第一行 n 表示点数。

 接下来 n-1 行,每行两个数 a,b 表示 a 和 b 之间有一条边。
点从 1 开始标号。 接下来一行 q 表示计划数。
对每个计划有 2 行,第一行 k 表示这个计划选中了几个点。
 第二行用空格隔开的 k 个互不相同的数表示选了哪 k 个点。
 

Output

输出 q 行,每行三个数分别表示代价和,最小代价,最大代价。

 

Sample Input

10
2 1
3 2
4 1
5 2
6 4
7 5
8 6
9 7
10 9
5
2
5 4
2
10 4
2
5 2
2
6 1
2
6 1

Sample Output

3 3 3
6 6 6
1 1 1
2 2 2
2 2 2
/*
f[i]表示以i为根的子树的路径和
f[i]=f[son[i]]+siz[son[y]]*(cnt-siz[son[y]])*dis(i,son[i])
maxs[i]表示以i为根的子树的节点到i的最大长度
用maxs[i]+maxs[son[i]]+dis(i,son[i])来更新答案。
然后在虚树上做DP
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 1000010
#define lon long long
#define inf 1000000000
using namespace std;
int n,m,dfn[N],dep[N],tim,fa[N][],a[N],num;
int g[N],sta[N],top,siz[N],mins[N],maxs[N],ans1,ans2;
lon f[N];
bool cmp(int x,int y){return dfn[x]<dfn[y];}
struct Node{
int head[N],son[N*],pre[N*],cnt;
void add(int u,int v){
son[++cnt]=v;pre[cnt]=head[u];head[u]=cnt;
}
void dfs1(int u){
dfn[u]=++tim;
for(int i=;i<=;i++) fa[u][i]=fa[fa[u][i-]][i-];
for(int i=head[u];i;i=pre[i])
if(son[i]!=fa[u][]){
fa[son[i]][]=u;
dep[son[i]]=dep[u]+;
dfs1(son[i]);
}
}
void dfs2(int x){
siz[x]=g[x];maxs[x]=;mins[x]=inf;f[x]=;
for(int i=head[x];i;i=pre[i]){
int d=dep[son[i]]-dep[x];
dfs2(son[i]);siz[x]+=siz[son[i]];
ans1=min(ans1,mins[x]+mins[son[i]]+d);
mins[x]=min(mins[x],mins[son[i]]+d);
ans2=max(ans2,maxs[x]+maxs[son[i]]+d);
maxs[x]=max(maxs[x],maxs[son[i]]+d);
f[x]+=f[son[i]]+1LL*siz[son[i]]*(num-siz[son[i]])*d;
}
if(g[x]) ans1=min(ans1,mins[x]),ans2=max(ans2,maxs[x]),mins[x]=;
head[x]=;
}
}g1,g2;
int lca(int a,int b){
if(dep[a]<dep[b]) swap(a,b);
int t=dep[a]-dep[b];
for(int i=;~i;i--) if(t&(<<i)) a=fa[a][i];
if(a==b) return a;
for(int i=;~i;i--)
if(fa[a][i]!=fa[b][i])
a=fa[a][i],b=fa[b][i];
return fa[a][];
}
void work(){
top=;
for(int i=;i<=num;i++){
if(!top){sta[++top]=a[i];continue;}
int anc=lca(a[i],sta[top]);
while(dep[anc]<dep[sta[top]]){
if(dep[anc]>=dep[sta[top-]]){
g2.add(anc,sta[top]);
top--;
if(sta[top]!=anc) sta[++top]=anc;
break;
}
else g2.add(sta[top-],sta[top]),top--;
}
if(sta[top]!=a[i]) sta[++top]=a[i];
}
while(top>) g2.add(sta[top-],sta[top]),top--;
ans1=inf;ans2=;g2.dfs2(sta[]);
printf("%lld %d %d\n",f[sta[]],ans1,ans2);
for(int i=;i<=num;i++) g[a[i]]=;g2.cnt=;
}
int main(){
scanf("%d",&n);
for(int i=;i<n;i++){
int u,v;scanf("%d%d",&u,&v);
g1.add(u,v);g1.add(v,u);
}
g1.dfs1();scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%d",&num);
for(int j=;j<=num;j++) scanf("%d",&a[j]),g[a[j]]=;
sort(a+,a+num+,cmp);
work();
}
return ;
}

大工程(bzoj 3611)的更多相关文章

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

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

  2. 【BZOJ】【3611】【HEOI2014】大工程

    虚树+树形DP 本题100W的点数……不用虚树真的好吗…… Orz ZYF 我的感悟: dp的过程跟SPOJ 1825 FTOUR2 的做法类似,依次枚举每个子树,从当前子树和之前的部分中各找一条最长 ...

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

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

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

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

  5. BZOJ 3611 大工程 (虚树)

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

  6. 3611: [Heoi2014]大工程

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

  7. 【BZOJ3611】大工程(虚树,动态规划)

    [BZOJ3611]大工程(虚树,动态规划) 题面 BZOJ Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树 ...

  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. 【jQeury】input输入框状态,input事件,blur事件,focus事件

    //输入框正在输入时 $("#test1").on('input',function(){ alert('正在输入'); }) //输入框得到焦点时 $("#test2& ...

  2. Git版本控制使用方法入门教程

    1. 概述 对于软件版本管理工具,酷讯决定摒弃CVS而转向Git了. 为什么要选择Git? 你真正学会使用Git时, 你就会觉得这个问题的回答是非常自然的.然而当真正需要用文字来回答时,却觉得文字好像 ...

  3. 第4章 HDFS操作

    目录 4.1 命令行操作 4.2 Java API操作 4.2.1 创建Java工程 4.2.2 读取数据 4.2.3 创建目录 4.2.4 创建文件 4.2.5 删除文件 4.2.6 遍历文件和目录 ...

  4. 数据分析处理库Pandas——数据透视表

    数据 按指定的行列值显示 求和 按行求和 按列求和 数据 求平均 备注:按性别计算每个等级船票的平均价格. 备注:每个等级船舱中每种性别获救的平均值,也就是获救的比例. 备注:每种性别未成年人获救的平 ...

  5. 使用shell脚本依据分区信息分批次的下载hive表格数据

    今天的业务场景大概是这样的,我想把hive表格下载到本地文件系统,然后把这个文件传送到另一个服务器上. 但是这个业务场景一个核心问题就是说我本地机器内存有限,hive表格大概是70G,我是不可能全部下 ...

  6. Card Hand Sorting 18中南多校第一场C题

    一.题意 随机给你一堆牌(标准扑克牌),之后让你按照: 第一优先规则:所有相同花色的在一起 第二优先规则:所有相同花色的必须按照升序或者降序排列 问,你最少要拿出多少张牌插入到其他的地方以维持这个状况 ...

  7. 笔记-python-语法-super

    笔记-python-语法-super 1.      super 1.1.    super起源 首先要理解类的继承和多继承,子类有时需要调用父类的方法, 非绑定方法: class C(B): def ...

  8. pdo事务

    $pdo->beginTransaction() $pdo->commit() $pdo->rollback();

  9. 腾讯QQ空间穿越时光轴3D特效

    <DOCTYPE html> <html> <head> <title>腾讯QQ空间穿越光轴3D特效</title> <style&g ...

  10. 使用Subversion进行源代码管理(二):创建和发布版本库[转]

    原文出处: http://www.blogjava.net/youxia/archive/2007/10/23/155372.html 我的上一篇随笔讲了怎么使用Subversion客户端去连接服务器 ...