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 ...
随机推荐
- oracle12c中新能优化新特性之热度图和自动数据优化
1. Oracle12c热度图和自动数据优化 信息生命周期管理(ILM)是指在数据生命周期内管理它们的策略.依赖于数据的年龄和对应用的业务相关性,数据能被压缩,能被归档或移到低成本的存储上.简言之,I ...
- for each...in,for...in, for...of
一.for each ...in explanation: 该语句在对象属性的所有值上迭代指定的变量.对于每个不同的属性,执行指定的语句. 句法: for each (variable in obj ...
- poj3020 二分图匹配 最大独立集
这是一道水题, 这里是最大流解法,之后再补 坑在又忘了反向建边了 题意:给你二维bool数组,让你求出能用多米诺骨牌覆盖所有 1 且骨牌最少的放法(因为多米诺骨牌1*2的结构方便描述,原题没有),原本 ...
- scrapy的selectors
from scrapy import Selector >>> doc = """ ... <div> ... <ul> ...
- 1.3 C++引用(Reference)
参考:http://www.weixueyuan.net/view/6328.html 总结: 引用是变量的另外一个别名,不是指针,与原变量名同指相同的内存.可以原变量的值. 在函数中作为形参可以修改 ...
- ABP .Net Core 调用异步方法抛异常A second operation started on this context before a previous asynchronous operation completed
1. 问题描述 最近使用ABP .Net Core框架做一个微信开发,同时采用了一个微信开发框架集成到ABP,在微信用户关注的推送事件里调用了一个async 方法,由于没有返回值,也没做任何处理,本 ...
- 2.3 linux中的信号分析 阻塞、未达
信号的阻塞.未达: linux中进程1向进程2发送信号,要经过内核,内核会维护一个进程对某个信号的状态,如下图所示: 当进程1向进程2发送信号时,信号的传递过程在内核中是有状态的,内核首先要检查这个信 ...
- LMS算法
一.感知器算法和LMS算法 感知器和自适应线性元件在历史上几乎是同时提出的,并且两者在对权值的调整的算法非常相似.它们都是基于纠错学习规则的学习算法. 感知器算法存在如下问题:不能推广到一般的前向网络 ...
- mac 搭建Vue开发环境
1: 使用的各个工具的版本为: Homebrew 1node.js npm webpack Vue 2: 安装brew 打开终端运行一下命令 /usr/bin/ruby -e "$(cur ...
- Windows Security Login
/********************************************************************************* * Windows Securit ...