bzoj2286消耗战 虚树+树型动规
来源:互联网 发布:家用网络交换机连接 编辑:程序博客网 时间:2024/05/22 12:47
2286: [Sdoi2011]消耗战
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3772 Solved: 1357
[Submit][Status][Discuss]
Description
在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。
侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到1号岛屿上)。不过侦查部门还发现了这台机器只能够使用m次,所以我们只需要把每次任务完成即可。
Input
第一行一个整数n,代表岛屿数量。
接下来n-1行,每行三个整数u,v,w,代表u号岛屿和v号岛屿由一条代价为c的桥梁直接相连,保证1<=u,v<=n且1<=c<=100000。
第n+1行,一个整数m,代表敌方机器能使用的次数。
接下来m行,每行一个整数ki,代表第i次后,有ki个岛屿资源丰富,接下来k个整数h1,h2,…hk,表示资源丰富岛屿的编号。
Output
输出有m行,分别代表每次任务的最小代价。
Sample Input
10
1 5 13
1 9 6
2 1 19
2 4 8
2 3 91
5 6 8
7 5 4
7 8 31
10 7 9
3
2 10 6
4 5 7 8 3
3 9 4 6
1 5 13
1 9 6
2 1 19
2 4 8
2 3 91
5 6 8
7 5 4
7 8 31
10 7 9
3
2 10 6
4 5 7 8 3
3 9 4 6
Sample Output
12
32
22
32
22
HINT
对于100%的数据,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1
Source
Stage2 day2
一道虚树模板题,然后树型动规
虚树,大概就是把树中用到的关键节点不改变原来树的结构重新建一颗形式上的树,所有操作都在这棵树上进行就可以了,类似于缩图,以达到简化操作复杂度的目的。(敷衍~)
对于这题来说,只有选中的点需要建树。如果是裸的树dp 就是f[i] = min(mn[i], sum(mn[son[k]]))
mn[i]表示i到根节点路径中最小边权。f[i]表示使其子树都无法到达根的最小代价。也就是说,对于某个点i,要么它的所有子树到不了根,要么它到不了根。
然后就是虚树的操作,具体看点击打开链接
然后每次建树,再dp就好啦
第一次调,调了一早上qwq(还是抄hzwer的)
#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<algorithm>#include<map>#include<cmath>#include<set>#define maxn 250005#define inf 1e60using namespace std;int read() { char ch = getchar(); int x = 0, f = 1; while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();} while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();} return x * f;} int pre[maxn][2], top;struct edge { int to, next, w; void add(int u, int v, int ww, bool p) { if(u == v) return; to = v; next = pre[u][p]; pre[u][p] = top++; w = ww; }}e[maxn * 2], e2[maxn * 2];int fa[maxn], deep[maxn], son[maxn], dson[maxn], d[maxn], in[maxn];int h[maxn], st[maxn];long long f[maxn], mn[maxn];int n, m, tot, cnt;void adds(int w, int v, int u) { e[top].add(u, v, w, 0); e[top].add(v, u, w, 0);} bool cmp(int x, int y) {return in[x] < in[y];} void dfs1(int u, int pa) { fa[u] = pa; deep[u] = deep[pa] + 1; son[u] = 1; dson[u] = 0; for(int i = pre[u][0]; i; i = e[i].next) { if(e[i].to == pa) continue; int v = e[i].to; mn[v] = min(mn[u], (long long)e[i].w); dfs1(v, u); son[u] += son[v]; if(son[v] > son[dson[u]]) dson[u] = v; }} void dfs2(int u, int chain) { in[u] = ++tot; d[u] = chain; if(!dson[u]) return; dfs2(dson[u], chain); for(int i = pre[u][0]; i; i = e[i].next) if(e[i].to != fa[u] && e[i].to != dson[u]) dfs2(e[i].to, e[i].to);} int lca(int u, int v) { while(d[u] != d[v]) { if(deep[d[u]] < deep[d[v]]) swap(u, v); u = fa[d[u]]; } if(in[u] > in[v]) swap(u, v); return u;} void init() { n = read(); top = 1; mn[1] = inf; for(int i = 1;i < n; ++i) { adds(read(), read(), read()); } dfs1(1, 0); dfs2(1, 1);} void dp(int u) { f[u] = mn[u]; long long tmp = 0; for(int i = pre[u][1]; i; i = e2[i].next) { dp(e2[i].to); tmp += f[e2[i].to]; } pre[u][1] = 0; if(tmp == 0) f[u] = mn[u]; else if(tmp <= f[u]) f[u] = tmp;} void solve() { int K = read(); top = 1; tot = 0; for(int i = 1;i <= K; ++i) h[i] = read(); sort(h + 1, h + K + 1, cmp); h[++tot] = h[1]; for(int i = 2;i <= K; ++i) if(lca(h[i], h[tot]) != h[tot]) h[++tot] = h[i]; st[++cnt] = 1; for(int i = 1;i <= tot; ++i) { int cur = h[i], pa = lca(cur, st[cnt]); while(1) { if(deep[pa] >= deep[st[cnt - 1]]) { e2[top].add(pa, st[cnt--], 0, 1); if(st[cnt] != pa) st[++cnt] = pa; break; } e2[top].add(st[cnt - 1], st[cnt], 0, 1); --cnt; } if(st[cnt] != cur) st[++cnt] = cur; } while(--cnt) e2[top].add(st[cnt], st[cnt + 1], 0, 1); dp(1); printf("%lld\n", f[1]);} int main(){ init(); m = read(); for(int i = 1;i <= m; ++i) solve(); return 0;}
阅读全文
0 0
- bzoj2286消耗战 虚树+树型动规
- [BZOJ2286][Sdoi2011消耗战] 虚树
- BZOJ2286: [Sdoi2011]消耗战 虚树
- 【bzoj2286】【sdoi2011】【消耗战】【虚树+dp】
- bzoj2286 消耗战 虚树&树形dp
- 【bzoj2286】[Sdoi2011消耗战 虚树+dp
- [虚树dp] bzoj2286: Sdoi2011消耗战
- BZOJ2286: [Sdoi2011]消耗战(虚树)
- bzoj2286 消耗战【虚树+树形dp】
- [虚树 + DP] BZOJ2286: [Sdoi2011]消耗战
- 【bzoj2286】 消耗战
- BZOJ2286 消耗战
- 虚树+树形dp bzoj2286【Sdoi2011】 消耗战
- BZOJ2286:消耗战(虚树,树形dp)
- [BZOJ2286][SDOI2011]消耗战(虚树+树形DP)
- BZOJ2286 [Sdoi2011]消耗战 【虚树 + 树形Dp】
- 【虚树+树形DP】BZOJ2286(Sdoi2011)[消耗战]题解
- bzoj2286: [Sdoi2011]消耗战
- 整数除法隐式转换
- C++sort函数关于数组、容器vector、字符串类string排序
- 支持嵌入至POS机安卓软件中的车牌识别sdk
- 20个非常有用的Java程序片段
- 面向面试编程?
- bzoj2286消耗战 虚树+树型动规
- 4027: [HEOI2015]兔子与樱花
- linux下部署PostgreSQL_yum安装_DNS服务器的问题
- Flask 电子邮件设置error553的解决办法
- C++ 动态规划-背包类
- nginx搭建及测试
- java io 层次结构图 io详解
- git版本控制的常见操作
- 浅谈Java的Fork/Join并发框架