BZOJ2286:[SDOI2011]消耗战(树形DP,虚树)
Description
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
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
32
22
HINT
对于100%的数据,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1
Solution
虚树真是个好东西啊QAQ
建议对虚树的理解看第一个,构建看第二个QAQ
题解去看第二个吧我也懒得写了XD
顺带提一句因为本题特殊,所以建虚树的时候要写成57行那样,否则就把57行删掉改成58行就行了。
至于本题为什么要像57行那么写呢……
假设$x$点是$y$的祖先,如果$x$到根不连通,那么$y$到根一定不连通,所以$y$点也就没有加进去的必要了。而且加进去的话像我这样$DP$也就不对了啊啊QAQQQQ
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#define N (250009)
#define LL long long
using namespace std; struct Edge{int to,next,len;}edge[N<<];
int n,m,k,u,v,l,dfs_num;
int a[N],Depth[N],f[N][],DFN[N];
LL Min[N];
int head[N],num_edge; void add(int u,int v,int l)
{
edge[++num_edge].to=v;
edge[num_edge].next=head[u];
edge[num_edge].len=l;
head[u]=num_edge;
} void DFS(int x,int fa)
{
f[x][]=fa;
for (int i=; i<=; ++i) f[x][i]=f[f[x][i-]][i-];
DFN[x]=++dfs_num; Depth[x]=Depth[fa]+;
for (int i=head[x]; i; i=edge[i].next)
if (edge[i].to!=fa)
{
Min[edge[i].to]=min(Min[x],(LL)edge[i].len);
DFS(edge[i].to,x);
}
} int LCA(int x,int y)
{
if (Depth[x]<Depth[y]) swap(x,y);
for (int i=; i>=; --i)
if (Depth[f[x][i]]>=Depth[y]) x=f[x][i];
if (x==y) return x;
for (int i=; i>=; --i)
if (f[x][i]!=f[y][i]) x=f[x][i], y=f[y][i];
return f[x][];
} vector<int>E[N];
void ADD(int x,int y) {E[x].push_back(y);}
int stack[N],top;
bool cmp(int x,int y) {return DFN[x]<DFN[y];} void Insert(int x)
{
if (top==) {stack[++top]=x; return;}
int lca=LCA(x,stack[top]);
if (lca==stack[top]) return;
// if (lca==stack[top]) {stack[++top]=x; return;}
while (top> && DFN[stack[top-]]>=DFN[lca])
ADD(stack[top-],stack[top]), top--;
if (lca!=stack[top]) ADD(lca,stack[top]), stack[top]=lca;
stack[++top]=x;
} void Build()
{
stack[top=]=;
for (int i=; i<=k; ++i) Insert(a[i]);
while (top>=) ADD(stack[top-],stack[top]), top--;
} LL DP(int x)
{
int sz=E[x].size();
if (!sz) return Min[x];
LL ans=;
for (int i=; i<sz; ++i)
ans+=DP(E[x][i]);
E[x].clear();
return min(ans,Min[x]);
} int main()
{
Min[]=1e18;
scanf("%d",&n);
for (int i=; i<=n-; ++i)
{
scanf("%d%d%d",&u,&v,&l);
add(u,v,l); add(v,u,l);
}
DFS(,);
scanf("%d",&m);
for (int i=; i<=m; ++i)
{
scanf("%d",&k);
for (int j=; j<=k; ++j) scanf("%d",&a[j]);
sort(a+,a+k+,cmp);
Build();
printf("%lld\n",DP());
}
}
BZOJ2286:[SDOI2011]消耗战(树形DP,虚树)的更多相关文章
- [luoguP2495] [SDOI2011]消耗战(DP + 虚树)
传送门 明显虚树. 别的题解里都是这样说的. 先不考虑虚树,假设只有一组询问,该如何dp? f[u]表示把子树u中所有的有资源的节点都切掉的最优解 如果节点u需要切掉了话,$f[u]=val[u]$ ...
- P2495 [SDOI2011]消耗战 lca倍增+虚树+树形dp
题目:给出n个点的树 q次询问 问切断 k个点(不和1号点联通)的最小代价是多少 思路:树形dp sum[i]表示切断i的子树中需要切断的点的最小代价是多少 mi[i]表示1--i中的最小边权 ...
- 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...
- 【CF809E】Surprise me! 树形DP 虚树 数学
题目大意 给你一棵\(n\)个点的树,每个点有权值\(a_i\),\(a\)为一个排列,求 \[ \frac{1}{n(n-1)}\sum_{i=1}^n\sum_{j=1}^n \varphi(a_ ...
- 3611: [Heoi2014]大project|树形DP|虚树
构建出虚树然后DP统计答案 自己写的DP太傻QAQ,各种WA 膜了一发PoPoQQQ大爷的DP方法 mxdis,mndis分别表示到当前点近期和最远的被选出来的点的距离 mx,mn分别表示在以当前点为 ...
- CF613D:Kingdom and its Cities(树形DP,虚树)
Description 一个王国有n座城市,城市之间由n-1条道路相连,形成一个树结构,国王决定将一些城市设为重要城市. 这个国家有的时候会遭受外敌入侵,重要城市由于加强了防护,一定不会被占领.而非重 ...
- BZOJ3611:[HEOI2014]大工程(树形DP,虚树)
Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通 ...
- 【BZOJ-1040】骑士 树形DP + 环套树 + DFS
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3312 Solved: 1269[Submit][Status ...
- HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
随机推荐
- 十九、curator recipes之PathChildrenCache
简介 curator可以监听路径下子节点的变更操作,如创建节点,删除节点 官方文档:http://curator.apache.org/curator-recipes/path-cache.html ...
- when coding in a fresh system
I have designed a component of a web system with my workmate. In detail, I am just a coder instead o ...
- LOJ #2985. 「WC2019」I 君的商店
传送门 搬题解QwQ 首先最大值一定为 \(1\),直接扫一遍两两比较 \(O(2N)\) 求出最大值 设最大值位置为 \(a\),对于任意两个没有确定的位置 \(x,y\) 询问 \([a,x+y] ...
- Hadoop总结
背景 Hadoop是一个由Apache基金会所开发的分布式系统基础架构.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Mapreduce1 vs YA ...
- AR中的SLAM(一)
写在前面 本系列打算讲讲个人对AR行业和AR中的SLAM算法的一点浅显的看法.才疏学浅,文中必然有很多疏漏和不足,还望能和大家多多讨论.今天先讲讲我对AR的一些认识. AR的一点理解 AR是什么 AR ...
- 润乾V4报表批量打印
背景说明 在应用中,经常遇到,批量打印的需求,批量打印,顾名思义,就是点击一次打印按钮,能打印多张报表. 下面,我们来介绍一下怎么样实现批量打印的 应用举例: Jsp代码 <% //rep ...
- OkHttp2.0有Bug,暂时不推荐在产品中使用
版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/4078137.html 之前在博客里推荐使用OkHttp来替换 ...
- Two tomcat 冲突
一.一般修改 路径: /opt/apache-tomcat/conf/server.xml 1.第一个tomcat使用默认配置 2.第二个tomcat一般配置 二.特殊修改 1.第二个tomcat特殊 ...
- python是如何找到对应的package的?
我们在写python代码或者阅读别人的代码时,可能会碰到对应module无法找到的问题,这时如何解决呢?我们如果对python解释器如何查找对应的module有比较深刻的理解,那么我们就可以轻松解决相 ...
- java中如何打war包
1.利用jdk里的工具 例如我们要打包的文件在D:\Project:运行 cmd: cd D:\Project 进入D:\Project ,然后输入jar -cvf Project.war *回 ...