「洛谷2495」「BZOJ3052」「SDOI2001」消耗战【虚树+树形动态规划】
题目大意
给你\(k\)个点,让这一些点和一号节点断开,删去某一些边,求最小的删去边权之和。
做题的心路历程
做了\(HG\)昨天的模拟赛,深深感觉到了窝的菜,所以为了\(A\)掉T1这一道毒瘤,窝就来学习一下虚树。
学到一半,感觉虚树的原理还是比较简单的,就是把需要求的点建一棵和原来的树长得十分相似的一棵树,然后在这个树上做\(DP\)。
但是,我写到完了,就一直T。也不知道为什么。
然后删掉了所有的memset
就瞬间跑了出来。原来是因为自己太怂了。。。
题解
首先如果考虑最简单的树形\(DP\)。
\(f[i]\)表示以\(i\)为根节点的答案。
那么我们需要预处理出每一个节点到根节点\(1\)的最小边权设为\(me[i]\),那么就得到了\(f[i]=\sum \ min(f[i],me[i])\)
但是发现,如果每一个询问都做一遍树形\(DP\),那么一定是要炸的。
那么就对于我们需要询问的节点建立一个树,然后在这个树上跑DP。
代码
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#define N 550005
#define ms(a, b) memset(a, b, sizeof(a))
#define ll long long
#define BIT 19
using namespace std;
template <typename T> void read(T &x) {x = 0; T fl = 1; char ch = 0;for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') fl = -1;for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);x *= fl;
}
struct edge { int to, nt, w; } E[N << 1];
vector<int> G[N];
int H[N], dfn[N], ispoint[N], f[N][BIT + 5], dep[N], p[N], stk[N];
ll me[N];
int cnt, __dfn, n, Q, k, top;
void add_edge(int u, int v, int w) { E[++ cnt] = (edge){v, H[u], w}; H[u] = cnt; }
bool cmp(int A, int B) { return dfn[A] < dfn[B]; }
void dfs1(int u, int fa) {f[u][0] = fa; dfn[u] = ++ __dfn; dep[u] = dep[fa] + 1; for (int i = 1; i <= BIT; i ++) f[u][i] = f[f[u][i - 1]][i - 1];for (int e = H[u]; e; e = E[e].nt) { int v = E[e].to; if (v == fa) continue; me[v] = E[e].w; if (u != 1 && me[u] < me[v]) me[v] = me[u]; dfs1(v, u); }
}
int lca(int u, int v) {if (dep[u] < dep[v]) swap(u, v);for (int i = BIT; ~i; i --) if (dep[f[u][i]] >= dep[v]) u = f[u][i]; if (u == v) return u;for (int i = BIT; ~i; i --) if (f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];return f[u][0];
}
void insert(int u) {if (top == 1) { stk[++ top] = u; return; }int Lca = lca(u, stk[top]);if (Lca == stk[top]) { stk[++ top] = u; return; }while (top > 1 && dfn[Lca] <= dfn[stk[top - 1]]) G[stk[top - 1]].push_back(stk[top]), -- top;if (Lca != stk[top]) G[Lca].push_back(stk[top]), stk[top] = Lca; stk[++ top] = u;
}
ll DP(int u) {ll res = 0;for (int i = 0; i < (int) G[u].size(); i ++) {int v = G[u][i]; res += min(me[v], DP(v));}G[u].clear(); if (ispoint[u]) return me[u]; else return res;
}
int main() {read(n); for (int i = 1, u, v, w; i < n; i ++) { read(u); read(v); read(w); add_edge(u, v, w); add_edge(v, u, w); }__dfn = 0; dfs1(1, 0);read(Q);while (Q --) {read(k); for (int i = 1; i <= k; i ++) read(p[i]), ispoint[p[i]] = 1; sort(p + 1, p + 1 + k, cmp); top = 0; stk[++ top] = 1; for (int i = 1; i <= k; i ++) insert(p[i]);while (top > 0) { G[stk[top - 1]].push_back(stk[top]); top --; } printf("%lld\n", DP(1));for (int i = 1; i <= k; i ++) G[p[i]].clear(), ispoint[p[i]] = 0; G[0].clear(); }return 0;
}
转载于:https://www.cnblogs.com/chhokmah/p/10695437.html
「洛谷2495」「BZOJ3052」「SDOI2001」消耗战【虚树+树形动态规划】相关推荐
- 「LuoguP4995」「洛谷11月月赛」 跳跳!(贪心
题目描述 你是一只小跳蛙,你特别擅长在各种地方跳来跳去. 这一天,你和朋友小 F 一起出去玩耍的时候,遇到了一堆高矮不同的石头,其中第 ii 块的石头高度为 h_ihi,地面的高度是 h_0 = 0 ...
- 【洛谷3345_BZOJ3924】[ZJOI2015]幻想乡战略游戏(点分树)
大概有整整一个月没更博客了 -- 4 月为省选爆肝了一个月,最后压线进 B 队,也算给 NOIP2018 翻车到 316 分压线省一这个折磨了五个月的 debuff 画上了一个不算太差的句号.结果省选 ...
- 2019.03.21【ZJOI2007】【BZOJ1095】【洛谷P2056】Hide 捉迷藏(DFS序)(线段树)
BZOJ传送门 洛谷传送门 解析: 其实就是QTREE4的弱化版,可以直接用QTREE4的解法来做. 但是这道题有优秀的O(nlogn)O(n\log n)O(nlogn)做法. 我们考虑利用DFS ...
- 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)
[模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...
- 「洛谷P1343」地震逃生 解题报告
P1343 地震逃生 题目描述 汶川地震发生时,四川XX中学正在上课,一看地震发生,老师们立刻带领x名学生逃跑,整个学校可以抽象地看成一个有向图,图中有n个点,m条边.1号点为教室,n号点为安全地带, ...
- 「洛谷P2397」 yyy loves Maths VI (mode) 解题报告
P2397 yyy loves Maths VI (mode) 题目背景 自动上次redbag用加法好好的刁难过了yyy同学以后,yyy十分愤怒.他还击给了redbag一题,但是这题他惊讶的发现自己居 ...
- 「洛谷P3469」[POI2008]BLO-Blockade 解题报告
P3469[POI2008]LO-Blockade 题意翻译 在Byteotia有n个城镇. 一些城镇之间由无向边连接. 在城镇外没有十字路口,尽管可能有桥,隧道或者高架公路(反正不考虑这些).每两个 ...
- 「洛谷」P1406 方格填数
P1406 方格填数 https://www.luogu.com.cn/problem/P1406 题目描述 给一个n 的方格矩阵,还有 n*n个整数,让你将这些整数填入矩阵,使得每行每列每个对角线上 ...
- 「洛谷 3768」简单的数学题
传送门 problem 给定 nnn 和 ppp,求: ∑i=1n∑j=1nijgcd(i,j)\sum_{i=1}^n\sum_{j=1}^nij\gcd(i,j)i=1∑nj=1∑nijgc ...
最新文章
- Nature:人类肠道微生物组的肠型
- RNN和LSTM的正向/前向传播-图示公式和代码
- mysql物理读和逻辑读,SQL Server中STATISTICS IO物理读和逻辑读的误区
- 【视频课】先搞懂你用的模型,深度学习模型分析课程来了!
- POJ-2407 欧拉函数
- Team Foundation Server简介
- (13) css浮动补充
- php访问方法外变量
- C#枚举中使用Flags特性
- Linux 压缩与解压缩工具之zip
- 数据挖掘原理与实践学习(3)
- word排版之长英文单词自动换行
- python制作地图
- CodeForces 1037E Trips(瞎搞)
- 常见的服务器类型有哪些?
- linux trace 进程 文件路径,linux panic 问题定位
- NDK实践(一)在linux环境下编译ffmpe
- Java 实现顺时针螺旋二维数组输出
- Java中world、PDF、Excel转图片
- 视频号的发布技巧,视频号打造受欢迎的内容:国仁楠哥
热门文章
- Moment.js常见用法总结
- 【Fedora20】 samba配置
- POSIX风格正则表达式
- 显示当前行号、文件名和函数名(二)
- 微信小程序下拉刷新列表onPullDownRefresh;微信小程序上划加载列表onReachBottom;uni-app微信小程序下拉加载数据;uni-app微信小程序上划页面加载数据
- Java 结构体之 JavaStruct 使用教程二 JavaStruct 用例分析
- [react] 举例说明如何在React创建一个事件
- 手把手教你封装一个ant design的审核框组件
- React开发(110):注意state定义的数据类型
- [html] 使用button当按钮和使用div当按钮有什么区别?