给出一个n节点的无向树,每条边都有一个边权,给出m个询问,
每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接。
最少的边权和是多少。
(n<=250000,sigma(ki)<=500000)

考虑树形DP,我们令mn[i]表示i节点无法与1节点相连切除的最小权值。
显然有mn[i]=min(E(fa,i),mn[fa]).
大致就是i到1的简单路径上的最小边。
我们对于每个询问。把询问的点不妨称为关键点。
令dp[i]表示i节点不能与子树的关键点连接切掉的最小权值。
那么有,如果son[i]是关键点,则dp[i]+=E(i,son(i)).
如果son[i]不是关键点,则dp[i]+=min(dp[son(i)],E(i,son(i))).

考虑最坏每次只询问一个点,则复杂度为O(n*sigma(ki)).显然无法承受。

我们观察到sigma(ki)有限制,这启发了我们构造一颗新树,这棵树称为虚树。
我们把每个节点和每对节点的lca单独拉出来模仿原来的树的形态构造一颗虚树。
这样再在这颗新树上进行树形DP。

构造这棵树的核心思想是每次维护一条最右边的链。
首先把关键点按dfs序排序。
然后相邻的点取lca。
再单调栈维护一下最右边的链就ok啦。

  1. # include <stdio.h>
  2. # include <string.h>
  3. # include <stdlib.h>
  4. # include <iostream>
  5. # include <vector>
  6. # include <queue>
  7. # include <stack>
  8. # include <map>
  9. # include <math.h>
  10. # include <algorithm>
  11. using namespace std;
  12. # define lowbit(x) ((x)&(-x))
  13. # define pi acos(-1.0)
  14. # define MAXN
  15. # define eps 1e-
  16. # define MAXM
  17. # define MOD
  18. # define INF
  19. # define mem(a,b) memset(a,b,sizeof(a))
  20. # define FOR(i,a,n) for(int i=a; i<=n; ++i)
  21. # define FO(i,a,n) for(int i=a; i<n; ++i)
  22. # define bug puts("H");
  23. typedef long long LL;
  24. typedef unsigned long long ULL;
  25. int _MAX(int a, int b){return a>b?a:b;}
  26. int _MIN(int a, int b){return a>b?b:a;}
  27. int Scan() {
  28. int res=, flag=;
  29. char ch;
  30. if((ch=getchar())=='-') flag=;
  31. else if(ch>=''&&ch<='') res=ch-'';
  32. while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
  33. return flag?-res:res;
  34. }
  35. void Out(int a) {
  36. if(a<) {putchar('-'); a=-a;}
  37. if(a>=) Out(a/);
  38. putchar(a%+'');
  39. }
  40.  
  41. struct Edge{int p, next, w;}edge[MAXN<<];
  42. int head[MAXN], cnt=, bin[], ind;
  43. int id[MAXN], dep[MAXN], fa[MAXN][], h[MAXN], st[MAXN], top;
  44. LL ans[MAXN], dp[MAXN];
  45.  
  46. void add_edge(int u, int v, int w)
  47. {
  48. if (u==v) return ;
  49. edge[cnt].p=v; edge[cnt].next=head[u]; edge[cnt].w=w; head[u]=cnt++;
  50. }
  51. void bin_init(){bin[]=; FO(i,,) bin[i]=bin[i-]<<;}
  52. bool comp(int a, int b){return id[a]<id[b];}
  53. void dfs(int x, int fat)
  54. {
  55. id[x]=++ind;
  56. fa[x][]=fat;
  57. for (int i=; bin[i]<=dep[x]; ++i) fa[x][i]=fa[fa[x][i-]][i-];
  58. for (int i=head[x]; i; i=edge[i].next) {
  59. int v=edge[i].p;
  60. if (v==fat) continue;
  61. dep[v]=dep[x]+;
  62. ans[v]=min(ans[x],(LL)edge[i].w);
  63. dfs(v,x);
  64. }
  65. }
  66. int lca(int x, int y)
  67. {
  68. if (dep[x]<dep[y]) swap(x,y);
  69. int t=dep[x]-dep[y];
  70. for (int i=; bin[i]<=t; ++i) if (bin[i]&t) x=fa[x][i];
  71. for (int i=; i>=; --i) if (fa[x][i]!=fa[y][i]) x=fa[x][i], y=fa[y][i];
  72. if (x==y) return x;
  73. else return fa[x][];
  74. }
  75. void dp_dfs(int x)
  76. {
  77. dp[x]=ans[x];
  78. LL temp=;
  79. for (int i=head[x]; i; i=edge[i].next) {
  80. int v=edge[i].p;
  81. dp_dfs(v);
  82. temp+=dp[v];
  83. }
  84. head[x]=;
  85. if (temp) dp[x]=min(dp[x],temp);
  86. }
  87. void sol()
  88. {
  89. int k, tot=;
  90. cnt=;
  91. scanf("%d",&k);
  92. FOR(i,,k) h[i]=Scan();
  93. sort(h+,h+k+,comp);
  94. h[++tot]=h[];
  95. FOR(i,,k) if (lca(h[tot],h[i])!=h[tot]) h[++tot]=h[i];
  96. st[++top]=;
  97. FOR(i,,tot) {
  98. int f=lca(h[i],st[top]);
  99. while (dep[f]<dep[st[top-]]) add_edge(st[top-],st[top],), top--;
  100. add_edge(f,st[top--],);
  101. if (f!=st[top]) st[++top]=f;
  102. st[++top]=h[i];
  103. }
  104. while (top>) add_edge(st[top-],st[top],), top--;
  105. dp_dfs();
  106. printf("%lld\n",dp[]);
  107. }
  108. int main()
  109. {
  110. int n, m, u, v, w;
  111. bin_init();
  112. n=Scan();
  113. FO(i,,n) u=Scan(), v=Scan(), w=Scan(), add_edge(u,v,w), add_edge(v,u,w);
  114. ans[]=(LL)<<; dfs(,);
  115. m=Scan();
  116. mem(head,);
  117. while (m--) sol();
  118. return ;
  119. }

BZOJ 2286 消耗战 (虚树+树形DP)的更多相关文章

  1. 【BZOJ-2286】消耗战 虚树 + 树形DP

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

  2. BZOJ.2286.[SDOI2011]消耗战(虚树 树形DP)

    题目链接 BZOJ 洛谷P2495 树形DP,对于每棵子树要么逐个删除其中要删除的边,要么直接断连向父节点的边. 如果当前点需要删除,那么直接断不需要再管子树. 复杂度O(m*n). 对于两个要删除的 ...

  3. BZOJ 2286: [Sdoi2011]消耗战 虚树 树形dp 动态规划 dfs序

    https://www.lydsy.com/JudgeOnline/problem.php?id=2286 wa了两次因为lca犯了zz错误 这道题如果不多次询问的话就是裸dp. 一棵树上多次询问,且 ...

  4. BZOJ 2286 消耗战 - 虚树 + 树型dp

    传送门 题目大意: 每次给出k个特殊点,回答将这些特殊点与根节点断开至少需要多少代价. 题目分析: 虚树入门 + 树型dp: 刚刚学习完虚树(好文),就来这道入门题签个到. 虚树就是将树中的一些关键点 ...

  5. 【BZOJ2286】【SDOI2011】消耗战 [虚树][树形DP]

    消耗战 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 在一场战争中,战场由n个岛屿和n-1 ...

  6. BZOJ2286: [Sdoi2011]消耗战(虚树/树形DP)

    Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5246  Solved: 1978[Submit][Status][Discuss] Descript ...

  7. bzoj 2286(虚树+树形dp) 虚树模板

    树链求并又不会写,学了一发虚树,再也不虚啦~ 2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5002  Sol ...

  8. BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP+树剖lca

    BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的 ...

  9. 【BZOJ-3572】世界树 虚树 + 树形DP

    3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1084  Solved: 611[Submit][Status ...

随机推荐

  1. 【再探backbone04】单页应用的基石-路由处理

    前言 首先发一点牢骚,互联网公司变化就是快,我去一个团队往往就一年时间该团队就得解散,这不,公司居然把无线团队解散了,我只能说,我那个去!!! 我去年还到处让人来呢,一个兴兴向荣的团队说没就没了啊!我 ...

  2. 获取WIFI密码

    在十年前,我还在上初中,班上只有极少数的富二代用得起手机:几年后诺基亚.摩托罗拉.三星手机开始盛行:近些年,安卓.苹果系统手机占据了基本整个市场,WIFI出变得越来越重要. Wifi万能钥匙数据库存储 ...

  3. SharePoint 2013 图文开发系列之可视化WebPart

    有了WebPart开发的基础,再进行可视化WebPart开发,就容易多了.创建和开发过程,两者非常相似,下面,我们简单介绍下可视化WebPart的开发. 1.添加新项目,选择SharePoint 20 ...

  4. [转]给 C# 开发者的代码审查清单

    这是为C#开发者准备的通用性代码审查清单,可以当做开发过程中的参考.这是为了确保在编码过程中,大部分通用编码指导原则都能注意到.对于新手和缺乏经验(0到3年工作经验)的开发者,参考这份清单编码会很帮助 ...

  5. Android开发学习——应用安装过程

    首先一个android项目,然后编译和打包,将.java文件编译为.class,.class编译为.dex,将所有文件打包为一个apk,只编译代码,不编译资源. .apk里面的.arsc是资源的索引, ...

  6. 【代码笔记】iOS-圆角矩形

    代码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. se ...

  7. IOS 杂笔-16 (-(void)scrollViewDidEndScrollingAnimation:方法使用注意)

    今天在写项目的时候,遇到了一件令人抓狂的事情. 正如标题所示,被这个方法弄的团团转. -(void)scrollViewDidEndScrollingAnimation:是协议里的方法. 意味当动画结 ...

  8. JVM-漫游

    Write once, Run Any where. Java Virtual Machine – JVM 的存在让 Java 开发变得简单,并且一次编写多处运行.其实,JVM 就是一个抽象的计算机, ...

  9. javascript - 封装原生js实现ajax

    1 /* * ajax方法 */ var Ajax = function() { var that = this; //创建异步请求对象方法 that.createXHR = function() { ...

  10. Python基础1

    本节内容2016-05-30 Python介绍 发展史 Python 2 0r 3? 安装 Hello word程序 变量 用户输入 模块初识 .pyc? 数据类型初识 数据运算 if...else语 ...