P2495 [SDOI2011]消耗战 lca倍增+虚树+树形dp
题目:给出n个点的树 q次询问 问切断 k个点(不和1号点联通)的最小代价是多少
思路:树形dp sum[i]表示切断i的子树中需要切断的点的最小代价是多少 mi[i]表示1--i中的最小边权
sum[i]=min(mi[i],sigma(min(mi[v],sum[v]) (v∈i.son))
从根向上dp 这里巧妙运用了欧拉序(每个点入和出的按时间顺序排列的序列)
题目链接:https://www.luogu.org/problemnew/show/P2495
参考:https://www.luogu.org/problemnew/solution/P2495
#include<bits/stdc++.h>
using namespace std;
const int maxn = ;
typedef long long ll;
const int N=maxn;
struct data{
int v;int nxt;ll val;
}edge[*maxn];
int dfu;
int dfin[N];//欧拉序入的时间戳
int dfou[N];//欧拉序列出的时间戳
int fa[][N];//倍增用
ll mi[N];//i到1号点路径中最小的边权
int dep[N]; //深度
int lca(int u,int v){//倍增lca
if(dep[u]<dep[v])swap(u,v);
int del=dep[u]-dep[v];
for(int i=;del;del>>=,i++){
if(del&){
u=fa[i][u];
}
}//到同一深度
if(u==v)return u;
for(int i=;i>=;i--){
if(fa[i][u]!=fa[i][v]){u=fa[i][u],v=fa[i][v];}
} //从到lca的距离的二进制理解 即可立即为什么fa[0][v]就是是lca
return fa[][v];
}
int alist[maxn],cnt;int n; void dfs(int x){
dfin[x]=++dfu;//首位是入 出 时间戳
for(int i=;fa[i-][x];i++){//更新父节点信息
fa[i][x]=fa[i-][fa[i-][x]];
}
int nxt=alist[x];
while(nxt){//更新最小边权
int v=edge[nxt].v,val=edge[nxt].val;
if(dfin[v]==){
dep[v]=dep[x]+;
mi[v]=min(mi[x],1ll*val);
fa[][v]=x;
dfs(v);
}
nxt=edge[nxt].nxt;
}
dfou[x]=++dfu;
return ;
}
inline void add(int u,int v,ll val)
{ edge[++cnt].v=v;
edge[cnt].nxt=alist[u];
alist[u]=cnt;
edge[cnt].val=val;
}
bool cmp(int x,int y){//分为正负即可方便得判断是入 还是出
int k1=(x>)?dfin[x]:dfou[-x];
int k2=(y>)?dfin[y]:dfou[-y];
return k1<k2;
}
int tr[*N];
stack<int>s;
int m;
bool book[N];
ll sum[N]; int main(){
scanf("%d",&n);
for(int i=;i<=n-;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,z);
}
mi[]=0x3f3f3f3f;
dfs();//建立欧拉序
scanf("%d",&m);
for(int i=;i<=m;i++){
int tmp;
scanf("%d",&tmp);
for(int j=;j<=tmp;j++){//把要求的点标记
scanf("%d",&tr[j]);
book[tr[j]]=;
sum[tr[j]]=mi[tr[j]];//初始化删除重要点的sum[i](sum指的是切断[i]的子树中所有重要点的最小代价 初始化为切掉该点即 从1--i的最小边权 意思是直接把这个子树切掉了)
}
sort(tr+,tr+tmp+,cmp);//对欧拉序列排序建立虚树
for(int j=;j<tmp;j++){
int lc=lca(tr[j],tr[j+]);
if(!book[lc]){//树的建立
tr[++tmp]=lc;
book[lc]=;
}
}
int nc=tmp;
for(int j=;j<=nc;j++){//把每个点的负时间戳也加入 用负数表示这个的点现在是出去的点
tr[++tmp]=-tr[j];
}
if(!book[]){//强行把1号点加进来当根
tr[++tmp]=;tr[++tmp]=-;
}
sort(tr+,tr+tmp+,cmp);//重构欧拉序
for(int j=;j<=tmp;j++){//模拟dfs 因为1--tmp是欧拉序列 所以可以直接用
if(tr[j]>)s.push(tr[j]);//进栈
else {
int now=s.top();s.pop();
if(now!=){
//状态转移方程sum[i]=sigma(min(mi[v],sum[v]) (v∈i.son)
int fa=s.top();
sum[fa]+=min(sum[now],mi[now]);
}
else printf("%lld\n",sum[]);
sum[now]=;
book[now]=false;
}
}
} return ;
}
P2495 [SDOI2011]消耗战 lca倍增+虚树+树形dp的更多相关文章
- BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP+树剖lca
BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的 ...
- 【BZOJ-2286】消耗战 虚树 + 树形DP
2286: [Sdoi2011消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2120 Solved: 752[Submit][Status] ...
- bzoj 2286(虚树+树形dp) 虚树模板
树链求并又不会写,学了一发虚树,再也不虚啦~ 2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5002 Sol ...
- 【BZOJ-3572】世界树 虚树 + 树形DP
3572: [Hnoi2014]世界树 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1084 Solved: 611[Submit][Status ...
- BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP
题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...
- [WC2018]通道——边分治+虚树+树形DP
题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...
- 2018.09.25 bzoj3572: [Hnoi2014]世界树(虚树+树形dp)
传送门 虚树入门题? 好难啊. 在学习别人的写法之后终于过了. 这道题dp方程很好想. 主要是不好写. 简要说说思路吧. 显然最优值只能够从子树和父亲转移过来. 于是我们先dfs一遍用儿子更新父亲,然 ...
- BZOJ2286 [Sdoi2011]消耗战 【虚树 + 树形Dp】
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 4261 Solved: 1552 [Submit][Sta ...
- BZOJ.2286.[SDOI2011]消耗战(虚树 树形DP)
题目链接 BZOJ 洛谷P2495 树形DP,对于每棵子树要么逐个删除其中要删除的边,要么直接断连向父节点的边. 如果当前点需要删除,那么直接断不需要再管子树. 复杂度O(m*n). 对于两个要删除的 ...
随机推荐
- iOS----------教你如何使用 GitHub Desktop
1.先创建一个工程项目Test 2.创建一个仓库Repository 3.提交到master(记得写标题) 4.推送到github上 5.创建仓库Respository成功
- Android 屏幕适配插件 ScreenMatch
概述 ScreenMatch是根据你的需要,生成需要适配的尺寸的文件,手机会根据屏幕相关参数自动寻找合适的尺寸文件 添加插件 如图,打开Android Studio的Settings设置,找到Plug ...
- 使用 WeihanLi.Npoi 操作 CSV
使用 WeihanLi.Npoi 操作 CSV Intro 最近发现 csv 文件在很多情况下都在使用,而且经过大致了解,csv 格式简单,相比 excel 文件要小很多,读取也很是方便,而且也很通用 ...
- 给IConfiguration写一个GetAppSetting扩展方法
给 IConfiguration 写一个 GetAppSetting 扩展方法 Intro 在 .net core 中,微软已经默认使用 appsettings.json 来代替 app.config ...
- Ubuntu上更改MySQL数据库数据存储目录
之前写过一篇博客"MySQL更改数据库数据存储目录",当时的测试环境是RHEL和CentOS,谁想最近在Ubuntu下面更改MySQL数据库数据存储目录时遇到了之前未遇到的问题,之 ...
- Ehcache入门经典:第一篇
ehcache主要是轻量级的缓存实现 ehcache.xml <?xml version="1.0" encoding="UTF-8"?> < ...
- Class.isAssignableFrom与instanceof的区别
isAssignableFrom 假设有两个类Class1和Class2.Class1.isAssignableFrom(Class2)表示: 类Class1和Class2是否相同. Class1是否 ...
- C#基础知识之类和结构体
虽然项目中一直在使用类.结构体等类型,仔细琢磨,还真无法系统的说出个所以然.记录一下类.结构体.类和结构体区别 一.类 对于类,大家都特别熟悉.简单的介绍一下类的结构,然后记录一下Class需要注意的 ...
- .NET CORE学习笔记系列(3)——ASP.NET CORE多环境标识
在开发项目的过程当中,生产环境与调试环境的配置是不一样的.比如连接字符串. ASP .NET CORE 支持利用环境变量来动态配置 JSON 文件.ASP.NET Core 引用了一个特定的环境变量 ...
- Linux之指令 重定向 文件覆盖>和文件追加>>
指令>和>>区别 指令 > : 如果文件存在,将原来文件的内容覆盖:原文件不存在则创建文件,再添加信息. 指令 >>:不会覆盖原文件内容,将内容追加到文件的尾部. ...