题面

洛谷

题解

虚树+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. SQL Server CLR全功略之一---CLR介绍和配置

    Microsoft SQL Server 现在具备与 Microsoft Windows .NET Framework 的公共语言运行时 (CLR) 组件集成的功能.CLR 为托管代码提供服务,例如跨 ...

  2. Luogu 4254 [JSOI2008]Blue Mary开公司

    BZOJ 1568 学习了一波李超线段树. 大佬blog 这个东西专门用来维护插入一条线段和区间/单点的最大/最小值. 插入的时候讨论: 1.如果当前结点上没有线段,那么直接插入. 2.如果当前结点上 ...

  3. Django-Web框架之Hello Django!

    1.首先我们配置guest目录下面的settings.py问,将我们的sign应用添加到项目中.如下图所示: 2.我们通过地址栏:http://127.0.0.1:8001/index/访问Djang ...

  4. Struts2获取Action中的数据

    当我们用Struts2框架开发时,经常有要获取jsp页面的数据或者在jsp中获取后台传过来的数据(Action),那么怎么去获取自己想要的数据呢? 后台获取前端数据: 在java程序中生成要获取字段的 ...

  5. OkHttp3的简单使用(一)

    一.导入 1)gradle方式: compile 'com.squareup.okhttp3:okhttp:3.8.0'(okhttp 最新版) compile 'com.squareup.okio: ...

  6. React学习笔记3

    React的生命周期   生命周期分为三个阶段   1.mounted(初始化的时候) 当我们看见页面元素从JSX变成了DOM节点时,React组件已经被载入(mounted)到页面中了   2.up ...

  7. C#常见编译报错

    mCaster.PlayAnim(ANIMID.ASTD); No overload for method 'PlayAnim' takes '1' arguments PlayAnim()内有两个参 ...

  8. C#多线程编程实战1.3等待线程

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  9. OO 抽象类与接口的区别

    抽象类与接口的区别 抽象类与接口的区别 一.抽象类:(抽象类适用于同一系列,并且有需要继承的成员) 概念: 1.使用abstract修饰: 2.抽象类中可以包含抽象方法: 3.抽象类只能被子类继承:( ...

  10. 条件编译,C语言条件编译详解

    条件编译是指预处理器根据条件编译指令,有条件地选择源程序代码中的一部分代码作为输出,送给编译器进行编译.主要是为了有选择性地执行相应操作,防止宏替换内容(如文件等)的重复包含.常见的条件编译指令如表 ...