题面

洛谷

题解

虚树+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. 【总结整理】面试pm常见的问题---摘自《人人都是产品经理》

    求职路上,“怼”来“怼”去的面试问题 人人都是产品经理社区 发布于 2018-10-29 19:53:06 举报 阅读数:1418 ​​在求职路上,面对那些被“怼”到过的面试问题,应该如何处理? 一个 ...

  2. 383. Ransom Note 在字典数组中查找笔记数组

    [抄题]: Given an arbitrary ransom note string and another string containing letters from all the magaz ...

  3. hadoop搭建好,启动服务后,无法从web界面访问50070

    在hadoop完全分布式搭建好以后,从主节点启动正常,使用jps查看启动的进程,正常,在几个从节点上使用jps查看,显示正常,但从web上输入下面网址: http://主节点IP:50070 无法正常 ...

  4. PostgreSQL的索引选型

    PostgreSQL里面给全文检索或者模糊查询加索引提速的时候,一般会有两个选项,一个是GIST类型,一个是GIN类型,官网给出的参考如下: There are substantial perform ...

  5. C语言多线程

    http://www.cnblogs.com/lixiaohui-ambition/archive/2012/07/26/2610336.html

  6. HDU 3365 New Ground (计算几何)

    题意:给定点A[0~n-1]和B[0],B[1],A[0].A[1]映射到B[0].B[1],求出其余点的映射B[2]~B[n-1]. 析:运用复数类,关键是用模板复数类,一直编译不过,我明明能编译过 ...

  7. Git教程--廖雪峰

    Git简介 1.Git是目前世界上最先进的分布式版本控制系统(没有之一) 2.集中式和分布式版本控制系统有什么区别呢?      区别在于历史版本维护的位置:Git本地仓库包含代码库还有历史库,在本地 ...

  8. Glide4.0使用

    导入 dependencies { compile 'com.github.bumptech.glide:glide:4.0.0' compile 'com.android.support:suppo ...

  9. 20145218张晓涵 PC平台逆向破解_advanced

    ---恢复内容开始--- 20145218张晓涵 PC平台逆向破解_advanced shellcode注入 基础知识 shellcode就是在利用溢出攻击溢出时要值入的代码,也就是溢出后去执行的代码 ...

  10. 用原生css实现高斯模糊、黑白等滤镜效果

    —引导— 在CSS3中,有一个强大的属性,那就是filter属性,filter顾名思义就是“滤镜”的意思,用filter属性可以让图片无需PS处理就达到一些简单的显示效果. —定义和使用— filte ...