题目:

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

HINT

n<=1000000

q<=50000并且保证所有k之和<=2*n 

题解:

先构造虚树,为了维护答案anssum,ansmin,ansmax我们需要维护每个点i的sonsum[i],maxdis[i],mindis[i],cnt[i]分别表示该点所在子树的所有特殊点到这一点的距离总和,该点所在子树中的一个特殊点到该点距离的最大值以及最小值,和该点所在子树中的特殊点数量和···具体怎么更新三个答案和维护这四个值看代码吧

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cmath>
  5. #include<ctime>
  6. #include<cctype>
  7. #include<cstring>
  8. #include<string>
  9. #include<algorithm>
  10. using namespace std;
  11. const int N=1e6+;
  12. inline int R()
  13. {
  14. char c;int f=;
  15. for(c=getchar();c<''||c>'';c=getchar());
  16. for(;c<=''&&c>='';c=getchar())
  17. f=(f<<)+(f<<)+c-'';
  18. return f;
  19. }
  20. int fst[N],go[N*],nxt[N*],tot,dfn[N],deep[N],g[N][],Cnt;
  21. int vir[N],tag[N],tmp,stack[N],top,vn,tn,par[N];
  22. int n,m,ansmax,ansmin,cnt[N],maxdis[N],mindis[N];
  23. long long anssum,sonsum[N];
  24. inline void comb(int a,int b)
  25. {
  26. nxt[++tot]=fst[a],fst[a]=tot,go[tot]=b;
  27. nxt[++tot]=fst[b],fst[b]=tot,go[tot]=a;
  28. }
  29. inline void comb1(int a,int b)
  30. {
  31. nxt[++tot]=fst[a],fst[a]=tot,go[tot]=b;
  32. }
  33. inline void dfs(int u,int fa)
  34. {
  35. dfn[u]=++Cnt;
  36. for(int e=fst[u];e;e=nxt[e])
  37. {
  38. int v=go[e];
  39. if(v==fa) continue;
  40. deep[v]=deep[u]+;g[v][]=u;
  41. dfs(v,u);
  42. }
  43. }
  44. inline int get(int a,int b)
  45. {
  46. int i,j;
  47. if(deep[a]<deep[b]) swap(a,b);
  48. for(i=;(<<i)<=deep[a];i++);i--;
  49. for(j=i;j>=;j--)
  50. if(deep[a]-(<<j)>=deep[b])
  51. a=g[a][j];
  52. if(a==b) return a;
  53. for(i=;i>=;i--)
  54. if(g[a][i]!=g[b][i])
  55. a=g[a][i],b=g[b][i];
  56. return g[a][];
  57. }
  58. inline void pre()
  59. {
  60. tot=stack[top=]=,tmp++,anssum=,ansmin=1e+,ansmax=;
  61. }
  62. inline bool cmp(int a,int b)
  63. {
  64. return dfn[a]<dfn[b];
  65. }
  66. inline void build()
  67. {
  68. sort(vir+,vir+vn+,cmp);
  69. vn=unique(vir+,vir+vn+)-vir-;tn=vn;
  70. for(int i=;i<=tn;i++)
  71. {
  72. if(!top)
  73. {
  74. par[vir[i]]=;stack[++top]=vir[i];fst[stack[top]]=;
  75. continue;
  76. }
  77. int lca=get(vir[i],stack[top]);
  78. while(deep[stack[top]]>deep[lca])
  79. {
  80. if(deep[stack[top-]]<deep[lca]) par[stack[top]]=lca;
  81. top--;
  82. }
  83. if(stack[top]!=lca)
  84. {
  85. par[lca]=stack[top];
  86. vir[++vn]=lca;
  87. stack[++top]=lca;fst[stack[top]]=;
  88. }
  89. stack[++top]=vir[i];fst[stack[top]]=;
  90. par[vir[i]]=lca;
  91. }
  92. sort(vir+,vir+vn+,cmp);
  93. }
  94. inline void dp(int u)
  95. {
  96. cnt[u]=(tag[u]==tmp?:);sonsum[u]=;
  97. maxdis[u]=;mindis[u]=(tag[u]==tmp?:1e+);
  98. for(int e=fst[u];e;e=nxt[e])
  99. {
  100. int v=go[e];dp(v);
  101. ansmin=min(ansmin,mindis[u]+mindis[v]+deep[v]-deep[u]);
  102. ansmax=max(ansmax,maxdis[u]+maxdis[v]+deep[v]-deep[u]);
  103. anssum+=(long long)cnt[u]*cnt[v]*(deep[v]-deep[u])+(long long)sonsum[u]*cnt[v]+(long long)sonsum[v]*cnt[u];
  104. maxdis[u]=max(maxdis[u],maxdis[v]+deep[v]-deep[u]);
  105. mindis[u]=min(mindis[u],mindis[v]+deep[v]-deep[u]);
  106. sonsum[u]+=(sonsum[v]+(long long)cnt[v]*(deep[v]-deep[u]));
  107. cnt[u]+=cnt[v];
  108. }
  109. }
  110. int main()
  111. {
  112. freopen("a.in","r",stdin);
  113. n=R();int a,b;
  114. for(int i=;i<n;i++)
  115. {
  116. a=R(),b=R();
  117. comb(a,b);
  118. }
  119. deep[]=;
  120. dfs(,);
  121. for(int i=;i<=;i++)
  122. for(int j=;j<=n;j++)
  123. g[j][i]=g[g[j][i-]][i-];
  124. m=R();
  125. while(m--)
  126. {
  127. vn=R();pre();
  128. for(int i=;i<=vn;i++) vir[i]=R(),tag[vir[i]]=tmp;
  129. build();
  130. for(int i=;i<=vn;i++) comb1(par[vir[i]],vir[i]);
  131. dp(vir[]);
  132. printf("%lld %d %d\n",anssum,ansmin,ansmax);
  133. }
  134. return ;
  135. }

刷题总结——大工程(bzoj3611)的更多相关文章

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

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

  2. 【BZOJ3611】[Heoi2014]大工程 欧拉序+ST表+单调栈

    [BZOJ3611][Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶 ...

  3. [BZOJ3611][Heoi2014]大工程

    [BZOJ3611][Heoi2014]大工程 试题描述 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上.  在 ...

  4. 【刷题】【LeetCode】000-十大经典排序算法

    [刷题][LeetCode]总 用动画的形式呈现解LeetCode题目的思路 参考链接 000-十大经典排序算法

  5. BZOJ3611:[HEOI2014]大工程(树形DP,虚树)

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

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

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

  7. BZOJ3611 [Heoi2014]大工程 【虚树】

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

  8. [BZOJ3611][Heoi2014]大工程(虚树上DP)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 2464  Solved: 1104[Submit][Statu ...

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

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

随机推荐

  1. linux程序安装及包管理

    程序包的封装类型: RPM软件包:扩展名为“.rpm”,使用rpm命令安装. DEB软件包:扩展名为“.deb”,使用DPKG包管理器. 源代码软件安装:程序员开发完成的原始代码,一般制作成“.tar ...

  2. axios的post请求方法---以Vue示例

    Axios向后端提交数据的参数格式是json,而并非用的是form传参,post表单请求提交时,使用的Content-Type是application/x-www-form-urlencoded,而使 ...

  3. Maven搭建Struts2+Spring3+Hibernate4框架

    做了三年多的JavaEE开发了,在平时的JavaEE开发中,为了能够用最快的速度开发项目,一般都会选择使用Struts2,SpringMVC,Spring,Hibernate,MyBatis这些开源框 ...

  4. 基于arcgis api for js高速公路智能化智慧公路养护WebGIS开源系统

    伴随着高速公路建设进程加快,其涉及信息量增大.类型多样.地点分布广,传统的信息管理方式已不适应公路建设迅速发展的需要,而目前能对高速公路在设计.施工.养护等阶段的各类信息综合进行管理的信息系统尚较少见 ...

  5. 01_1JAVA简介

    01_1JAVA简介 1. Java基础 语法基础.OO.Exception.Array.基础类.I/O Stream.Collection /Generic.Thread.TCP/UDP.GUI.M ...

  6. iOS9适配总结

    每年iOS升级,都会带来一些坑,这次iOS9也不例外.本文总结了微信在适配iOS9上遇到的问题和解决方案. 一.iOS9问题汇总   1. 编译问题(Bitcode) 大部分人升级到Xcode7后,首 ...

  7. numpy的linspace使用详解

    文档地址: https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html Parameters(参数): start ...

  8. DNS 工作原理是什么,域名劫持、域名欺骗、域名污染又是什么

    DNS 工作原理是什么,域名劫持.域名欺骗.域名污染又是什么 2014年11月27日 10:05:40 阅读数:6726 标签: dns网络互联网顶级域名递归 更多 个人分类: 网络学习   一.DN ...

  9. pandas中数据聚合【重点】

    数据聚合 数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值. 数据分类处理: 分组:先把数据分为几组 用函数处理:为不同组的数据应用不同的函数以转换数据 合并:把不同组得到的结果合 ...

  10. Unity基础-Input接口

    input 底层的设备输入接口,在开发中很少用到 Input.GetKey() // Update is called once per frame void Update () { if (Inpu ...