题面

洛谷

题解

虚树+dp

关于虚树

了解一下

  • 具体实现
inline void insert(int x) {
if (top == 1) {s[++top] = x; return ;}
int lca = query(x, s[top]);
while (top > 1 && dfn[s[top-1]] >= dfn[lca]) t[s[top-1]].push_back(s[top]), top--;
if (lca != s[top]) t[lca].push_back(s[top]), s[top] = lca;
s[++top] = x;
return ;
} bool cmp(int a, int b) {
return dfn[a] < dfn[b];
}//dfn为在dfs序上的位置 main() {//o为输入的关键点
sort(o+1, o+1+k, cmp);
s[top = 1] = 1;
for (int i = 1; i <= k; i++) insert(o[i]);
for (int i = 1; i < top; i++) t[s[i]].push_back(s[i+1]);
}

然后对于这个虚树\(dp\)

\(a\)数组表示当前点到根这条链路径最小值

Code

#include<bits/stdc++.h>

#define LL long long
#define RG register using namespace std; inline int gi() {
RG int x = 0; RG char c = getchar(); bool f = 0;
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') c = getchar(), f = 1;
while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
return f ? -x : x;
}
const int N = 250010, INF = 2147483647;
struct node {
int to, next, w;
}g[N<<1];
int last[N], gl;
inline void add(int x, int y, int z) {
g[++gl] = (node) {y, last[x], z};
last[x] = gl;
return ;
}
int anc[N][21], dfn[N], cnt, dep[N], a[N];
void init(int u, int fa) {
anc[u][0] = fa;
dfn[u] = ++cnt;
for (int i = 1; i <= 20; i++)
anc[u][i] = anc[anc[u][i-1]][i-1];
for (int i = last[u]; i; i = g[i].next) {
int v = g[i].to;
if (v == fa) continue;
dep[v] = dep[u]+1;
a[v] = min(g[i].w, a[u]);
init(v, u);
}
return ;
}
inline int query(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (int i = 20; i >= 0; i--)
if (dep[anc[x][i]] >= dep[y])
x = anc[x][i];
if (x == y) return x;
for (int i = 20; i >= 0; i--)
if (anc[x][i] != anc[y][i])
x = anc[x][i], y = anc[y][i];
return anc[x][0];
} vector<int> t[N];
int o[N], s[N], top; bool cmp(int a, int b) {
return dfn[a] < dfn[b];
}
inline void insert(int x) {
if (top == 1) {s[++top] = x; return ;}
int lca = query(x, s[top]);
if (lca == s[top]) return ;//祖先都走不到,它肯定也走不到哈
while (top > 1 && dfn[s[top-1]] >= dfn[lca]) t[s[top-1]].push_back(s[top]), top--;
if (lca != s[top]) t[lca].push_back(s[top]), s[top] = lca;
s[++top] = x;
return ;
} LL dp(int u) {
LL S = 0;
if (!t[u].size()) return a[u];
for (int i = 0; i < (int)t[u].size(); i++) {
int v = t[u][i];
S += dp(v);
}
t[u].clear();
if (u==1) return S;
return min(S, 1ll*a[u]);
} int main() {
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
int n = gi();
for (int i = 1; i < n; i++) {
int x = gi(), y = gi(), z = gi();
add(x, y, z); add(y, x, z);
}
a[1] = INF;
init(1, 0);
int m = gi();
while (m--) {
int k = gi();
for (int i = 1; i <= k; i++)
o[i] = gi();
sort(o+1, o+1+k, cmp);
s[top = 1] = 1;
for (int i = 1; i <= k; i++) insert(o[i]);
for (int i = 1; i < top; i++)
t[s[i]].push_back(s[i+1]);
printf("%lld\n", dp(1));
}
return 0;
}

洛谷 P2495 [SDOI2011]消耗战(虚树,dp)的更多相关文章

  1. bzoj 2286(洛谷 2495) [Sdoi2011]消耗战——虚树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2286 https://www.luogu.org/problemnew/show/P2495 ...

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

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

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

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

  4. ●洛谷P2495 [SDOI2011]消耗战

    题链: https://www.luogu.org/problemnew/show/P2495题解: 虚树入门,树形dp 推荐博客:http://blog.csdn.net/lych_cys/arti ...

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

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

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

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

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

    题面 传送门 题解 为啥一直莫名其妙\(90\)分啊--重构了一下代码才\(A\)掉-- 先考虑直接\(dp\)怎么做 树形\(dp\)的时候,记一下断开某个节点的最小值,就是从根节点到它的路径上最短 ...

  8. [洛谷P2495][SDOI2011]消耗战

    题目大意:有一棵$n(n\leqslant2.5\times10^5)$个节点的带边权的树,$m$个询问,每次询问给出$k(\sum\limits_{i=1}^mk_i\leqslant5\times ...

  9. 洛谷 P3233 [HNOI2014]世界树(虚树+dp)

    题面 luogu 题解 数据范围已经告诉我们是虚树了,考虑如何在虚树上面\(dp\) 以下摘自hzwer博客: 构建虚树以后两遍dp处理出虚树上每个点最近的议事处 然后枚举虚树上每一条边,考虑其对两端 ...

随机推荐

  1. 为什么说Java String 类型的值是不可改变的?

    String对象是不可变的,它的内容是不能改变的.下列代码会改变字符串的内容吗? 1 2 String s = "Java"; s = "HTML"; 答案是不 ...

  2. MYSQL优化——索引覆盖

    索引覆盖:如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要进行到磁盘中找数据,若果查询得列不是索引的一部分则要到磁盘中找数据. 建表: create table test_ind ...

  3. hdu 4740 The Donkey of Gui Zhou

    1.扯犊子超多if else 判断的代码,华丽丽的TLE. #include<stdio.h> #include<string.h> #define N 1010 int ma ...

  4. plsql中查看sql执行计划

    想要优化sql语句,可以从sql执行计划入手. 在plsql客户端,提供了一个方便的按钮来查看执行计划 选中需要查看的sql语句,点击此按钮,就可以看到该条语句的执行计划了. 结果集包括描述,用户,对 ...

  5. 二度xml<一>

    又一次学习Xml,之前差不多都忘了,为了下半年的面试,为了工作重头来过....... 其实我觉得直接上代码来的更实际点,理论的东西,我们随便找点书看看就行. 下面的代码是为了打印出一个xml文件 xm ...

  6. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)

    一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...

  7. XE中FMX操作ListBox,添加上千条记录(含图片)

    我之前是想在ListBox的每个Item上添加一个图片,Item上所有的内容都是放在Object里赋值,结果发现加载一百条记录耗时四五秒: procedure TMainForm.AddItem; v ...

  8. 解决dragsort鼠标拖动与onclick事件共存

  9. 学习使用MS SQL Server游标(CURSOR)

    说实的,使用MS SQL Server这样久,游标一直没有使用过.以前实现相似的功能,都是使用WHILE循环加临时表来实现.刚才有参考网上示例练习写了一下.了解到游标概念与语法. 下面代码示例中,先是 ...

  10. 细说Mammut大数据系统测试环境Docker迁移之路

    欢迎访问网易云社区,了解更多网易技术产品运营经验. 前言 最近几个月花了比较多精力在项目的测试环境Docker迁移上,从最初的docker"门外汉"到现在组里的同学(大部分测试及少 ...