【 bzoj 2286 】 : [Sdoi2011]消耗战 - 树形DP
来源:互联网 发布:思科网络技术学院邮箱 编辑:程序博客网 时间:2024/05/07 09:44
这道题的思路感觉挺赞的……
暴力的DP,f[i]表示切到i点的最小代价,显然有
这其中中间有很多dp都是不必要的,因为如果一条链D下来,那么两个关键点之间更新的权值都是相邻两点的距离,可以省略掉。
然后就可以用一个应该是挺经典的做法:用单调栈维护一条链。
这样思路就很明显了,先按dfs序排序,然后用单调栈维护一条当前DP的链,每当加入一个新的关键点的时候就看看它是不是接在了链上,不然就一直往上跑也就是弹栈,直到接到了链上,在弹的过程中DP就可以了。
感觉这个做法可以用在很多跟删除连接关键点的边有关的题目里面。
#include <bits/stdc++.h>using namespace std;#define rep(i,a,b) for(int i = a , _ = b ; i <= _ ; i ++)#define per(i,a,b) for(int i = a , _ = b ; i >= _ ; i --)#define fore(i,u) for(int i = head[u] ; i ; i = nxt[i] )#define maxn 250007#define maxm 500007inline int rd() { char c = getchar(); while (!isdigit(c)) c = getchar() ; int x = c - '0'; while (isdigit(c = getchar())) x = x * 10 + c - '0'; return x;}template<class T> inline void upmin(T&a , T b) { if (a > b) a = b ; }typedef long long ll;const ll inf = 1ll << 60 ;typedef int arr_int[maxn];typedef ll arr_ll [maxn];typedef int adj[maxm];arr_int head , pos , dep , h , st , g;arr_ll f;adj to , nxt , val ;int dis[maxn][19];int fa[maxn][19];int n , ett , dfs_clock , top;inline void ins(int u , int v , int w) { to[++ ett] = v , val[ett] = w , nxt[ett] = head[u] , head[u] = ett;}void dfs(int u) { pos[u] = ++ dfs_clock; rep (i , 1 , 18) fa[u][i] = fa[fa[u][i - 1]][i - 1] , dis[u][i] = min(dis[fa[u][i - 1]][i - 1] , dis[u][i - 1]); fore (i , u) { int v = to[i] , w = val[i]; if (v == fa[u][0]) continue; dep[v] = dep[u] + 1 , fa[v][0] = u , dis[v][0] = w; dfs(v); }}inline int lca(int u , int v) { if (dep[u] < dep[v]) swap(u , v); int d = dep[u] - dep[v]; rep (i , 0 , 18) if ((1 << i) & d) u = fa[u][i]; if (u == v) return u; per (i , 18 , 0) if (fa[u][i] != fa[v][i]) u = fa[u][i] , v = fa[v][i]; return fa[u][0];}inline ll Dis(int u , int v) { if (dep[u] < dep[v]) swap(u , v); int d = dep[u] - dep[v]; int ret = 0x7fffffff; rep (i , 0 , 18) if ((1 << i) & d) upmin(ret , dis[u][i]) , u = fa[u][i]; if (u == v) return ret; per (i , 18 , 0) if (fa[u][i] != fa[v][i]) upmin(ret , min(dis[u][i] , dis[v][i])) , u = fa[u][i] , v = fa[v][i]; upmin(ret , min(dis[u][0] , dis[v][0])); return (ll) ret;}void input() { n = rd(); rep (i , 2 , n) { int u = rd() , v = rd() , w = rd(); ins(u , v , w) , ins(v , u , w); } dep[1] = 1 , dfs(1);}void work(int k) { st[top = 1] = 1; f[top] = g[top] = 0; rep (i , 1 , k) { int p = lca(st[top] , h[i]); while (dep[st[top]] > dep[p]) { if (dep[st[top - 1]] <= dep[p]) { ll tmp = min(g[top] ? inf : f[top] , Dis(p , st[top])); st[top --] = 0; if (st[top] != p) { st[++ top] = p; f[top] = 0 , g[top] = 0; } f[top] += tmp; break; } else { f[top - 1] += min(g[top] ? inf : f[top] , Dis(st[top - 1] , st[top])); st[top --] = 0; } } if (st[top] != h[i]) { st[++ top] = h[i]; f[top] = 0; } g[top] = 1; } for (;top > 1; st[top --] = 0) f[top - 1] += min(g[top] ? inf : f[top] , Dis(st[top - 1] , st[top])); printf("%lld\n" , f[1]);}bool cmp(const int a , const int b) { return pos[a] < pos[b];}void solve() { rep (m , 1 , rd()) { int k = rd(); rep (i , 1 , k) h[i] = rd(); sort(h + 1 , h + k + 1 , cmp); work(k); }}int main() { #ifndef ONLINE_JUDGE freopen("data.txt" , "r" , stdin); #endif input(); solve(); return 0;}
0 0
- 【 bzoj 2286 】 : [Sdoi2011]消耗战 - 树形DP
- bzoj 2286: [Sdoi2011消耗战 虚树+树形dp
- 【BZOJ】2286 [Sdoi2011]消耗战 树形DP+虚树
- bzoj 2286: [Sdoi2011消耗战 (虚树+树形DP)
- [虚树+树形DP]BZOJ 2286—— [Sdoi2011]消耗战
- 2286: [Sdoi2011消耗战|树形DP|虚树
- 【BZOJ】2286: [Sdoi2011消耗战【虚树DP】
- bzoj 2286 SDOI2011 消耗战 虚树dp
- 【BZOJ 2286】[Sdoi2011消耗战 虚树+dp
- bzoj 2286: [Sdoi2011]消耗战 虚树 DP
- BZOJ 2286: [Sdoi2011]消耗战
- bzoj 2286: [Sdoi2011]消耗战
- bzoj 2286: [Sdoi2011]消耗战
- BZOJ 2286: [Sdoi2011]消耗战
- bzoj 2286 [Sdoi2011]消耗战 虚树
- BZOJ 2286 [Sdoi2011]消耗战 虚树
- 虚树+树形dp bzoj2286【Sdoi2011】 消耗战
- [BZOJ2286][SDOI2011]消耗战(虚树+树形DP)
- OpenCV 实践程序17——实现图片标注
- 《java》笔记<七>
- WAF防火墙
- OpenStack 对象存储 Swift 简单介绍
- 希赛网 > 问答 > 程序开发 > Web开发 > Web前端 > Firefox下载文件中文乱码的一种Server端解决办法 Firefox下载文件中文乱码的一种Server端解决办法
- 【 bzoj 2286 】 : [Sdoi2011]消耗战 - 树形DP
- MySQL创建索引
- 最少换乘
- 自定义View弹出,周围变暗,点击view以外的区域,view消失及变亮。
- explain extend
- Mysql的索引类型和创建方法
- Android学习笔记——自定义TextView模仿验证码效果
- UICollectionView详解
- java jsonp接口