题目链接

  我虚树没很理解啊qwq

  就是我们有比较少的询问点,然后我们把不需要考虑的点搞一搞扔掉,然后每次询问给那些询问点单独建一颗树,然后乱搞。

  ……好吧看来是完全没理解……

  链接大法qwq

  

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cctype>
  6. #define maxn 500000
  7. using namespace std;
  8. inline long long read(){
  9. long long num=,f=;
  10. char ch=getchar();
  11. while(!isdigit(ch)){
  12. if(ch=='-') f=-;
  13. ch=getchar();
  14. }
  15. while(isdigit(ch)){
  16. num=num*+ch-'';
  17. ch=getchar();
  18. }
  19. return num*f;
  20. }
  21.  
  22. struct Edge{
  23. int next,to,val;
  24. }edge[maxn*];
  25. int head[maxn],num;
  26. inline void add(int from,int to,int val){
  27. edge[++num]=(Edge){head[from],to,val};
  28. head[from]=num;
  29. }
  30.  
  31. int stack[maxn],top;
  32. int deep[maxn];
  33. int s[maxn][];
  34. int dfn[maxn],ID;
  35. int q[maxn];
  36. long long f[maxn];
  37. long long ans[maxn];
  38. bool flag[maxn];
  39.  
  40. void dfs(int x,int fa){
  41. deep[x]=deep[fa]+; dfn[x]=++ID;
  42. for(int i=head[x];i;i=edge[i].next){
  43. int to=edge[i].to;
  44. if(to==fa) continue;
  45. s[to][]=x;
  46. f[to]=min(f[x],(long long)edge[i].val);
  47. dfs(to,x);
  48. }
  49. return;
  50. }
  51.  
  52. bool cmp(int a,int b){ return dfn[a]<dfn[b]; }
  53.  
  54. int calclca(int a,int b){
  55. if(deep[a]<deep[b]) swap(a,b);
  56. int f=deep[a]-deep[b];
  57. for(int i=;<<i<=f;++i)
  58. if(f&(<<i)) a=s[a][i];
  59. if(a==b) return a;
  60. for(int i=;i>=;--i){
  61. if(s[a][i]==s[b][i]) continue;
  62. a=s[a][i];b=s[b][i];
  63. }
  64. return s[a][];
  65. }
  66.  
  67. void calc(int x,int fa){
  68. long long sum=;
  69. ans[x]=f[x];
  70. for(int i=head[x];i;i=edge[i].next){
  71. int to=edge[i].to;
  72. if(to==fa) continue;
  73. calc(to,x);
  74. sum+=ans[to];
  75. }
  76. if(sum&&!flag[x]) ans[x]=min(ans[x],sum);
  77. head[x]=;
  78. return;
  79. }
  80.  
  81. int main(){
  82. f[]=1e9; f[]=f[]*f[];
  83. int n=read();
  84. for(int i=;i<n;++i){
  85. int from=read(),to=read(),val=read();
  86. add(from,to,val);
  87. add(to,from,val);
  88. }
  89. dfs(,);
  90. for(int i=;i<=;++i)
  91. for(int j=;j<=n;++j)
  92. s[j][i]=s[s[j][i-]][i-];
  93. int m=read();
  94. memset(head,,sizeof(head));
  95. for(int i=;i<=m;++i){
  96. num=;top=;
  97. int x=read();
  98. for(int j=;j<=x;++j){ q[j]=read();flag[q[j]]=; }
  99. sort(q+,q+x+,cmp);
  100. for(int j=;j<=x;++j){
  101. if(top==){
  102. stack[++top]=q[j];
  103. continue;
  104. }
  105. int lca=calclca(q[j],stack[top]);
  106. while(dfn[lca]<dfn[stack[top]]){
  107. if(dfn[lca]>=dfn[stack[top-]]){
  108. add(lca,stack[top],);
  109. if(stack[--top]!=lca) stack[++top]=lca;
  110. break;
  111. }
  112. add(stack[top-],stack[top],);
  113. top--;
  114. }
  115. stack[++top]=q[j];
  116. }
  117. while(top>){
  118. add(stack[top-],stack[top],);
  119. top--;
  120. }
  121. calc(stack[],stack[]);
  122. printf("%lld\n",ans[stack[]]);
  123. for(int j=;j<=x;++j) flag[q[j]]=;
  124. }
  125. return ;
  126. }

【Luogu】P2495消耗战(虚树DP)的更多相关文章

  1. [BZOJ2286][SDOI2011]消耗战(虚树DP)

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

  2. bzoj 2286 [Sdoi2011]消耗战 虚树+dp

    题目大意:多次给出关键点,求切断边使所有关键点与1断开的最小费用 分析:每次造出虚树,dp[i]表示将i和i子树与父亲断开费用 对于父亲x,儿子y ①y为关键点:\(dp[x]\)+=\(dismn( ...

  3. 【BZOJ】2286: [Sdoi2011]消耗战 虚树+DP

    [题意]给定n个点的带边权树,每次询问给定ki个特殊点,求隔离点1和特殊点的最小代价.n<=250000,Σki<=500000. [算法]虚树+DP [题解]考虑普通树上的dp,设f[x ...

  4. [SDOI2011][bzoj2286] 消耗战 [虚树+dp]

    题面: 传送门 思路: 看到所有询问中的点数总和是十万级别的,就想到用虚树~\(≧▽≦)/~啦 首先,树形dp应该是很明显可以看出来的: 设dp[u]表示以u为根的子树(不包括u)中的宝藏岛全部切断的 ...

  5. 洛谷P2495 [SDOI2011]消耗战(虚树dp)

    P2495 [SDOI2011]消耗战 题目链接 题解: 虚树\(dp\)入门题吧.虚树的核心思想其实就是每次只保留关键点,因为关键点的dfs序的相对大小顺序和原来的树中结点dfs序的相对大小顺序都是 ...

  6. bzoj 3572世界树 虚树+dp

    题目大意: 给一棵树,每次给出一些关键点,对于树上每个点,被离它最近的关键点(距离相同被标号最小的)控制 求每个关键点控制多少个点 分析: 虚树+dp dp过程如下: 第一次dp,递归求出每个点子树中 ...

  7. [SDOI2011]消耗战(虚树+树形动规)

    虚树dp 虚树的主要思想: 不遍历没用的的节点以及没用的子树,从而使复杂度降低到\(\sum\limits k\)(k为询问的节点的总数). 所以怎么办: 只把询问节点和其LCA放入询问的数组中. 1 ...

  8. [BZOJ5287][HNOI2018]毒瘤(虚树DP)

    暴力枚举非树边取值做DP可得75. 注意到每次枚举出一个容斥状态的时候,都要做大量重复操作. 建立虚树,预处理出虚树上两点间的转移系数.也可动态DP解决. 树上倍增.动态DP.虚树DP似乎是这种问题的 ...

  9. BZOJ 3572 [HNOI2014]世界树 (虚树+DP)

    题面:BZOJ传送门 洛谷传送门 题目大意:略 细节贼多的虚树$DP$ 先考虑只有一次询问的情况 一个节点$x$可能被它子树内的一个到x距离最小的特殊点管辖,还可能被管辖fa[x]的特殊点管辖 跑两次 ...

随机推荐

  1. java入门第一章——java开发入门

    习题解答 一.填空题 (p2)1.java的三个技术平台分别是(java SE.java EE.java ME)(标准.企业.小型) (p3)2.java程序的运行环境简称为(JRE)(开发环境-JD ...

  2. Nuget~管理自己的包包

    很久很久以前,自己就想有个包包,最近又从网上淘了一个,价格不便宜呢,99块,还是个小腰包,不过作工还算精良,我喜欢的类型,帆布休闲包,可以将我的手机,耳机,水,小烟,小酒,小伞都放里,方便至极,哈哈!

  3. ES6学习笔记(二)

    Set 和 Map 数据结构 1.set 基本用法 ES6提供了新的数据结构Set,它类似于数组,但是成员的值都是唯一的,没有重复的值 Set本身是一个构造函数,用来生成Set数据结构 const s ...

  4. python_84_os模块

    'os模块:提供对操作系统进行调用的接口' import os print(os.getcwd())#获取当前脚本工作目录,即当前Python脚本工作的目录路径 os.chdir('C:\\Users ...

  5. tomcat - CPU高占用问题记录

    先查询进程 top 再根据进程号,查出进程的线程 ps p 3036 -L -o pcpu,pid,tid,time,tname,cmd 得到最高使用率CPU的线程TID,转换成16进制 printf ...

  6. 酷炫的3D照片墙

    今天给大家分享的案例是酷炫的3D照片墙 这个案例主要是通过 CSS3 和原生的 JS 来实现的,接下来我给大家分享一下这个效果实现的过程.博客上不知道怎么放本地视频,所以只能放两张效果截图了. 1.实 ...

  7. 洛谷P2347 砝码称重

    题目 貌似是某年提高组签到题,六重循环零压力AC,差点怒踩std 但本蒟蒻决定写正解——多重背包,果断20分 原因是写错了状态转移方程...神才知道我咋过的样例和两个测试点 扯远了 多重背包 简单说一 ...

  8. redis学习笔记(1)

    最近在学习redis,做了比较详细的学习笔记,分享给大家,欢迎一起讨论和学习 第一部分,简单介绍redis 和 redis的基本操作 NoSQL的特点 : 数据库种类繁多,但是一个共同的特点都是去掉关 ...

  9. 使用jmeter做简单的压测(检查点、负载设置、聚合报告)

    1.添加断言(检查点) 在需要压测的接口下添加--断言--响应断言,取接口响应中包含有的数据即可 检查点HTTP请求-->断言-->响应断言1.名称.注释2.Apply to//作用于哪里 ...

  10. 【linux】文件默认权限:umask

    在默认权限的属性上,目录与文件是不一样的.从第六章我们知道 x 权限对於目录是非常重要的! 但是一般文件的创建则不应该有运行的权限,因为一般文件通常是用在於数据的记录嘛!当然不需要运行的权限了. 因此 ...