题目描述

在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。

侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到1号岛屿上)。不过侦查部门还发现了这台机器只能够使用m次,所以我们只需要把每次任务完成即可。

输入输出格式

输入格式:

第一行一个整数n,代表岛屿数量。

接下来n-1行,每行三个整数u,v,w,代表u号岛屿和v号岛屿由一条代价为c的桥梁直接相连,保证1<=u,v<=n且1<=c<=100000。

第n+1行,一个整数m,代表敌方机器能使用的次数。

接下来m行,每行一个整数ki,代表第i次后,有ki个岛屿资源丰富,接下来k个整数h1,h2,…hk,表示资源丰富岛屿的编号。

输出格式:

输出有m行,分别代表每次任务的最小代价。

输入输出样例

输入样例#1: 复制

  1. 10
  2. 1 5 13
  3. 1 9 6
  4. 2 1 19
  5. 2 4 8
  6. 2 3 91
  7. 5 6 8
  8. 7 5 4
  9. 7 8 31
  10. 10 7 9
  11. 3
  12. 2 10 6
  13. 4 5 7 8 3
  14. 3 9 4 6
输出样例#1: 复制

  1. 12
  2. 32
  3. 22

说明

【数据规模和约定】

对于10%的数据,2<=n<=10,1<=m<=5,1<=ki<=n-1

对于20%的数据,2<=n<=100,1<=m<=100,1<=ki<=min(10,n-1)

对于40%的数据,2<=n<=1000,m>=1,sigma(ki)<=500000,1<=ki<=min(15,n-1)

对于100%的数据,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1

如果是单次询问,可以$O(n)$的树dp做出来

这题询问数很多,但$k$的和不大

对于每次询问,我们建一棵“虚树”

这棵虚树只包括询问点以及相应的lca

这样在虚树上dp复杂度为$O(k)$

总复杂度为$O(\sumk)$

树dp可以这样Min[x]表示1~x路径上最小的边

f[x]表示1无法到达x子树中关键点的最小和

f[x]=min(Min[x],∑f[v])

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. using namespace std;
  7. typedef long long lol;
  8. const int N=;
  9. struct Node
  10. {
  11. int next,to;
  12. lol dis;
  13. }edge[N],edge2[N];
  14. int head[N],head2[N],num,dep[N],a[N],s[N],cnt,dfn[N];
  15. int fa[N][],vis[N],n,top,bin[],ed[N],M;
  16. lol Min[N];
  17. int gi()
  18. {
  19. char ch=getchar();
  20. int x=;
  21. while (ch<''||ch>'') ch=getchar();
  22. while (ch>=''&&ch<='')
  23. {
  24. x=x*+ch-'';
  25. ch=getchar();
  26. }
  27. return x;
  28. }
  29. bool cmp(int a,int b)
  30. {
  31. return dfn[a]<dfn[b];
  32. }
  33. void add(int u,int v,lol w)
  34. {
  35. num++;
  36. edge[num].next=head[u];
  37. head[u]=num;
  38. edge[num].to=v;
  39. edge[num].dis=w;
  40. }
  41. void dfs(int x,int pa)
  42. {int i;
  43. dep[x]=dep[pa]+;
  44. dfn[x]=++cnt;
  45. for (i=;bin[i]<=dep[x];i++)
  46. fa[x][i]=fa[fa[x][i-]][i-];
  47. for (i=head[x];i;i=edge[i].next)
  48. {
  49. int v=edge[i].to;
  50. if (v==pa) continue;
  51. Min[v]=min(Min[x],edge[i].dis);
  52. fa[v][]=x;
  53. dfs(v,x);
  54. }
  55. ed[x]=cnt;
  56. }
  57. int lca(int x,int y)
  58. {int as,i;
  59. if (dep[x]<dep[y]) swap(x,y);
  60. for (i=;i>=;i--)
  61. if (bin[i]<=dep[x]-dep[y])
  62. x=fa[x][i];
  63. if (x==y) return x;
  64. for (i=;i>=;i--)
  65. {
  66. if (fa[x][i]!=fa[y][i])
  67. {
  68. x=fa[x][i];y=fa[y][i];
  69. }
  70. }
  71. return fa[x][];
  72. }
  73. void add2(int u,int v)
  74. {
  75. if (u==v) return;
  76. num++;
  77. edge2[num].next=head2[u];
  78. head2[u]=num;
  79. edge2[num].to=v;
  80. }
  81. lol dp(int x)
  82. {int i;
  83. if (vis[x])
  84. return Min[x];
  85. lol tmp=;
  86. for (i=head2[x];i;i=edge2[i].next)
  87. {
  88. int v=edge2[i].to;
  89. tmp+=dp(v);
  90. }
  91. head2[x]=;
  92. return min(tmp,Min[x]);
  93. }
  94. int main()
  95. {int i,u,v,j,q,k;
  96. lol w;
  97. cin>>n;
  98. bin[]=;
  99. for (i=;i<=;i++)
  100. bin[i]=bin[i-]*;
  101. for (i=;i<=n-;i++)
  102. {
  103. scanf("%d%d%lld",&u,&v,&w);
  104. add(u,v,w);add(v,u,w);
  105. }
  106. Min[]=2e15;
  107. dfs(,);
  108. cin>>q;
  109. while (q--)
  110. {
  111. k=gi();
  112. M=k;
  113. num=;
  114. for (i=;i<=k;i++)
  115. a[i]=gi(),vis[a[i]]=;
  116. sort(a+,a+k+,cmp);
  117. for (i=;i<=k;i++)
  118. if (ed[a[i-]]<dfn[a[i]])
  119. a[++M]=lca(a[i-],a[i]);a[++M]=;
  120. sort(a+,a+M+,cmp);
  121. M=unique(a+,a+M+)-a-;
  122. s[++top]=a[];
  123. for (i=;i<=M;i++)
  124. {
  125. while (top&&ed[s[top]]<dfn[a[i]]) top--;
  126. add2(s[top],a[i]);
  127. s[++top]=a[i];
  128. }
  129. printf("%lld\n",dp());
  130. for (i=;i<=M;i++)
  131. vis[a[i]]=head2[a[i]]=;
  132. }
  133. }

[SDOI2011]消耗战的更多相关文章

  1. BZOJ 2286: [Sdoi2011]消耗战

    2286: [Sdoi2011消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2082  Solved: 736[Submit][Status] ...

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

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 在一 ...

  3. bzoj千题计划254:bzoj2286: [Sdoi2011]消耗战

    http://www.lydsy.com/JudgeOnline/problem.php?id=2286 虚树上树形DP #include<cmath> #include<cstdi ...

  4. 【LG2495】[SDOI2011]消耗战

    [LG2495][SDOI2011]消耗战 题面 洛谷 题解 参考博客 题意 给你\(n\)个点的一棵树 \(m\)个询问,每个询问给出\(k\)个点 求将这\(k\)个点与\(1\)号点断掉的最小代 ...

  5. AC日记——[SDOI2011]消耗战 洛谷 P2495

    [SDOI2011]消耗战 思路: 建虚树走树形dp: 代码: #include <bits/stdc++.h> using namespace std; #define INF 1e17 ...

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

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

  7. BZOJ2286 [Sdoi2011]消耗战 【虚树 + 树形Dp】

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 4261  Solved: 1552 [Submit][Sta ...

  8. 【BZOJ2286】[Sdoi2011]消耗战 虚树

    [BZOJ2286][Sdoi2011]消耗战 Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的 ...

  9. 2286: [Sdoi2011]消耗战

    2286: [Sdoi2011]消耗战 链接 分析 虚树练习题. 构建虚树,在虚树上DP. 跟着gxb学虚-tree... 代码 #include <cstdio> #include &l ...

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

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

随机推荐

  1. python的PEP8 代码风格指南

    PEP8 代码风格指南 这篇文章原文实际上来自于这里:https://www.python.org/dev/peps/pep-0008/ 知识点 代码排版 字符串引号 表达式和语句中的空格 注释 版本 ...

  2. Java 中 compareTo方法问题

    compareTo方法原理:先读取出字符串的第一个“字母”进行比较,比较的方法是ascii码表的值(字符所对应的十进制值),如果前面的大那么返回1,后面的大返回-1:此位置相同,继续比较下一位,直到最 ...

  3. stringify 字符串转化成json方法

    参照原文:http://www.cnblogs.com/damonlan/ http://www.jb51.net/article/29893.htm stringify的作用主要是序列化对象(转化为 ...

  4. 16-TypeScript装饰器模式

    在客户端脚本中,有一个类通常有一个方法需要执行一些操作,当我们需要扩展新功能,增加一些操作代码时,通常需要修改类中方法的代码,这种方式违背了开闭的原则. 装饰器模式可以动态的给类增加一些额外的职责.基 ...

  5. C#中委托。

    委托(delegate):是一个类型.其实winform中控件的事件也是特殊的委托类型. 如: 自定义委托:自定义委托在winform中的用法. 当要在子线程中更新UI时,必须通过委托来实现. pri ...

  6. Java 持久化操作之 --io流与序列化

    1)File类操作文件的属性 1.File类的常用方法 1. 文件的绝对完整路径:getAbsolutePath() 文件名:getName() 文件相对路径:getPath() 文件的上一级目录:g ...

  7. 有货前端 Web-APM 实践

    有货前端 Web-APM 实践 0 背景 有货电商技术架构上采用的是前后端分离,前端是主要以业务展示和接口聚合为主,拥有自己的 BFF (Backend For Frontend),以 nodejs ...

  8. Step by Step 真正从零开始,TensorFlow详细安装入门图文教程!帮你完成那个最难的从0到1

    摘要: Step by Step 真正从零开始,TensorFlow详细安装入门图文教程!帮你完成那个最难的从0到1 安装遇到问题请文末留言. 悦动智能公众号:aibbtcom AI这个概念好像突然就 ...

  9. Spring Security 入门(1-2)Spring Security - 从 配置例子例子 开始我们的学习历程

    1.Spring Security 的配置文件 我们需要为 Spring Security 专门建立一个 Spring 的配置文件,该文件就专门用来作为 Spring Security 的配置. &l ...

  10. lambda匿名函数透析

    lambda匿名函数透析 目录 1       匿名函数的作用... 1 2       匿名函数的格式... 1 3       匿名函数实例代码... 3   1         匿名函数的作用 ...