bzoj 2286(洛谷 2495) [Sdoi2011]消耗战——虚树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2286
https://www.luogu.org/problemnew/show/P2495
学习(抄)了 hzwer 的代码,觉得写得很好。http://hzwer.com/6188.html
有一个 “如果排序后第 i 个关键点和第 i-1 个关键点的 lca 是第 i-1 个关键点,就舍弃第 i 个关键点” 的操作,觉得很好。
把 hd[ ] 数组清空写在了 dfs 里,觉得很好。
自己一开始写了一个倍增找链上边权最小值,用来给虚树的边赋值,参考之后发现只要记录一个 “到根的路径上的最小边权” 就行了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
ll Mx(ll a,ll b){return a>b?a:b;}
ll Mn(ll a,ll b){return a<b?a:b;} const int N=,K=;const ll INF=3e10+;//for dp
int n,hd[N],xnt,to[N<<],nxt[N<<],w[N<<];
int dep[N],pre[N][K],bin[K],dfn[N],tim; ll mn[N];
bool cmp(int a,int b){return dfn[a]<dfn[b];}
void add(int x,int y,int z){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=z;}
void dfs(int cr,int fa)
{
dfn[cr]=++tim; dep[cr]=dep[fa]+;
pre[cr][]=fa;
for(int t=;bin[t]<=dep[cr];t++)
pre[cr][t]=pre[pre[cr][t-]][t-];
for(int i=hd[cr],v;i;i=nxt[i])
if((v=to[i])!=fa)
{
mn[v]=Mn(mn[cr],w[i]);
dfs(v,cr);
}
}
int get_lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
int d=dep[x]-dep[y];
for(int t=;bin[t]<=d;t++)
if(d&bin[t])x=pre[x][t]; if(x==y)return x;
for(int t=;t>=;t--)
if(pre[x][t]!=pre[y][t])
x=pre[x][t],y=pre[y][t];
return pre[x][];
}
namespace Tr{
int hd[N],xnt,to[N],nxt[N];
int p[N],tot,sta[N],top; ll dp[N];
void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
void get_tr()
{
xnt=;
sort(p+,p+tot+,cmp);
int lm=tot; p[tot=]=p[];
for(int i=;i<=lm;i++)
if(get_lca(p[i],p[tot])!=p[tot])p[++tot]=p[i];
sta[top=]=;
for(int i=;i<=tot;i++)
{
int u=p[i], lca=get_lca(u,sta[top]);
while(top&&dfn[lca]<dfn[sta[top]])
{
if(dfn[sta[top-]]<dfn[lca])
add(lca,sta[top]);
else add(sta[top-],sta[top]);
top--;
}
if(sta[top]!=lca)sta[++top]=lca;
sta[++top]=u;
}
for(int i=;i<top;i++)add(sta[i],sta[i+]);
}
void dfs(int cr)
{
if(!hd[cr]){dp[cr]=mn[cr];return;}
dp[cr]=;
for(int i=hd[cr],v;i;i=nxt[i])
{
dfs(v=to[i]); dp[cr]+=dp[v];
}
hd[cr]=;//////
dp[cr]=Mn(dp[cr],mn[cr]);
}
void solve()
{
int k=rdn(); tot=;
for(int i=,d;i<=k;i++)
d=rdn(),p[++tot]=d;
get_tr(); dfs(); printf("%lld\n",dp[]);
}
}
int main()
{
bin[]=;for(int i=;i<=;i++)bin[i]=bin[i-]<<;
n=rdn();
for(int i=,u,v,z;i<n;i++)
u=rdn(),v=rdn(),z=rdn(),add(u,v,z),add(v,u,z);
mn[]=INF; dfs(,);
int Q=rdn(); while(Q--)Tr::solve();
return ;
}
bzoj 2286(洛谷 2495) [Sdoi2011]消耗战——虚树的更多相关文章
- bzoj 2286: [Sdoi2011]消耗战 虚树+树dp
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description 在一 ...
- BZOJ.2286.[SDOI2011]消耗战(虚树 树形DP)
题目链接 BZOJ 洛谷P2495 树形DP,对于每棵子树要么逐个删除其中要删除的边,要么直接断连向父节点的边. 如果当前点需要删除,那么直接断不需要再管子树. 复杂度O(m*n). 对于两个要删除的 ...
- 洛谷 P2495 [SDOI2011]消耗战(虚树,dp)
题面 洛谷 题解 虚树+dp 关于虚树 了解一下 具体实现 inline void insert(int x) { if (top == 1) {s[++top] = x; return ;} int ...
- 洛谷P2495 [SDOI2011]消耗战(虚树dp)
P2495 [SDOI2011]消耗战 题目链接 题解: 虚树\(dp\)入门题吧.虚树的核心思想其实就是每次只保留关键点,因为关键点的dfs序的相对大小顺序和原来的树中结点dfs序的相对大小顺序都是 ...
- BZOJ 2286: [Sdoi2011]消耗战 虚树 树形dp 动态规划 dfs序
https://www.lydsy.com/JudgeOnline/problem.php?id=2286 wa了两次因为lca犯了zz错误 这道题如果不多次询问的话就是裸dp. 一棵树上多次询问,且 ...
- bzoj 2286 [Sdoi2011]消耗战 虚树+dp
题目大意:多次给出关键点,求切断边使所有关键点与1断开的最小费用 分析:每次造出虚树,dp[i]表示将i和i子树与父亲断开费用 对于父亲x,儿子y ①y为关键点:\(dp[x]\)+=\(dismn( ...
- 【BZOJ】2286: [Sdoi2011]消耗战 虚树+DP
[题意]给定n个点的带边权树,每次询问给定ki个特殊点,求隔离点1和特殊点的最小代价.n<=250000,Σki<=500000. [算法]虚树+DP [题解]考虑普通树上的dp,设f[x ...
- 洛谷P2495 [SDOI2011]消耗战(虚树)
题面 传送门 题解 为啥一直莫名其妙\(90\)分啊--重构了一下代码才\(A\)掉-- 先考虑直接\(dp\)怎么做 树形\(dp\)的时候,记一下断开某个节点的最小值,就是从根节点到它的路径上最短 ...
- BZOJ 2286 [Sdoi2011]消耗战 ——虚树
虚树第一题. 大概就是建一颗只与询问有关的更小的新树,然后在虚树上DP #include <map> #include <ctime> #include <cmath&g ...
随机推荐
- Hibernate---hbm2ddl和数据库方言的配置
Hibernate---hbm2ddl和数据库方言的配置 hibernate配置文件--hbm2ddl.auto属性值的区别: update: 最常用的取值,如果但其数据库中不存在表结构,那么自动创建 ...
- 体验异步的终极解决方案-ES7的Async/Await
阅读本文前,期待您对promise和ES6(ECMA2015)有所了解,会更容易理解.本文以体验为主,不会深入说明,结尾有详细的文章引用. 第一个例子 Async/Await应该是目前最简单的异步方案 ...
- 使用路径arc-七彩
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> < ...
- 安装docker CE for CentOS
Uninstall old versions sudo yum remove docker \ docker-client \ dock ...
- memory prefix retro,re out 2
1● retro retr əu 向后,倒退 2● re 重新,一再, 不,反向后
- 3.strcpy使用注意(3)
void test3(char * str1) { if(str1==NULL) { return; } char string[10]; if(strlen(str1)<=10) { strc ...
- golang模拟动态高优先权优先调度算法
实验二 动态高优先权优先调度 实验内容 模拟实现动态高优先权优先(若数值越大优先权越高,每运行一个时间单位优先权-n,若数值越小优先权越高,没运行一个时间单位优先权+n),具体如下: 设置进程体:进 ...
- pymysql 返回数据为字典形式(key:value--列:值)
一.需求 在数据库的操作中,有时需要直接返回数据库表中的栏位名称+栏位值的key:value这种字典格式的方法. Python DB-API使用流程: 引入API模块. 获取与数据库的连接. 执行SQ ...
- 使用array_merge重新排列数组下标
array_merge() 函数把两个或多个数组合并为一个数组. 如果键名有重复,该键的键值为最后一个键名对应的值(后面的覆盖前面的).如果数组是数字索引的,则键名会以连续方式重新索引. 注释:如果仅 ...
- Dev GridView-Bind Detail Grid during runtime
Here is a simple example. ASPX <%@ Page Language="C#" AutoEventWireup="true" ...