传送门

又一道虚树入门题。

这个dp更简单啊。

直接记录每个点到1的距离,简单转移就行了。

代码:

#include<bits/stdc++.h>
#define N 250005
#define ll long long
#define min(a,b) (a<b?a:b)
using namespace std;
inline ll read(){
	ll ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
int n,q,m,First[N],first[N],cnt=0,dfn_cnt=0,tot=0,top=0,stk[N],dfn[N],dep[N],st[N][21],a[N];
ll dis[N],f[N];
bool col[N];
struct edge{int v,next,w;}e[N<<1];
inline void add(int u,int v,int w){e[++cnt].v=v,e[cnt].w=w,e[cnt].next=First[u],First[u]=cnt;}
inline void Add(int u,int v){e[++cnt].v=v,e[cnt].next=first[u],first[u]=cnt;}
inline void dfs(int p){
	dfn[p]=++dfn_cnt;
	for(int i=First[p];i;i=e[i].next){
		int v=e[i].v;
		if(v==st[p][0])continue;
		st[v][0]=p,dep[v]=dep[p]+1,dis[v]=min(dis[p],e[i].w),dfs(v);
	}
}
inline int lca(int x,int y){
	if(dep[x]<dep[y])x^=y,y^=x,x^=y;
	for(int i=20;~i;--i)if(dep[x]-(1<<i)>=dep[y])x=st[x][i];
	if(x==y)return x;
	for(int i=20;~i;--i)if(st[x][i]!=st[y][i])x=st[x][i],y=st[y][i];
	return st[x][0];
}
inline bool cmp(int x,int y){return dfn[x]<dfn[y];}
inline void dfs1(int p){
	f[p]=dis[p];
	ll sum=0;
	for(int i=first[p];i;i=e[i].next){
		int v=e[i].v;
		dfs1(v),sum+=f[v];
	}
	if(sum&&!col[p])f[p]=min(f[p],sum);
	first[p]=0;
}
int main(){
	n=read(),dis[1]=1e18;
	for(int i=1;i<n;++i){
		int u=read(),v=read(),w=read();
		add(u,v,w),add(v,u,w);
	}
	dfs(1),cnt=0;
	for(int j=1;j<=20;++j)for(int i=1;i<=n;++i)st[i][j]=st[st[i][j-1]][j-1];
	q=read();
	while(q--){
		m=read(),tot=cnt=top=0;
		for(int i=1;i<=m;++i)a[i]=read(),col[a[i]]=true;
		sort(a+1,a+m+1,cmp);
		int t;
		for(int i=1;i<=m;++i){
			if(!top){stk[++top]=a[i];continue;}
			t=lca(a[i],stk[top]);
			while(dep[stk[top]]>dep[t]){
				if(dep[stk[top-1]]<=dep[t]){
					Add(t,stk[top]),--top;
					if(stk[top]!=t)stk[++top]=t;
					break;
				}
				Add(stk[top-1],stk[top]),--top;
			}
			stk[++top]=a[i];
		}
		while(top>1)Add(stk[top-1],stk[top]),--top;
		dfs1(stk[1]),printf("%lld\n",f[stk[1]]);
		for(int i=1;i<=m;++i)col[a[i]]=0;
	}
	return 0;
}

2018.09.25 bzoj2286: [Sdoi2011]消耗战(虚树+树形dp)的更多相关文章

  1. BZOJ2286: [Sdoi2011]消耗战(虚树/树形DP)

    Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5246  Solved: 1978[Submit][Status][Discuss] Descript ...

  2. 【BZOJ-2286】消耗战 虚树 + 树形DP

    2286: [Sdoi2011消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2120  Solved: 752[Submit][Status] ...

  3. BZOJ 2286: [Sdoi2011]消耗战 虚树 树形dp 动态规划 dfs序

    https://www.lydsy.com/JudgeOnline/problem.php?id=2286 wa了两次因为lca犯了zz错误 这道题如果不多次询问的话就是裸dp. 一棵树上多次询问,且 ...

  4. BZOJ.2286.[SDOI2011]消耗战(虚树 树形DP)

    题目链接 BZOJ 洛谷P2495 树形DP,对于每棵子树要么逐个删除其中要删除的边,要么直接断连向父节点的边. 如果当前点需要删除,那么直接断不需要再管子树. 复杂度O(m*n). 对于两个要删除的 ...

  5. [BZOJ2286][SDOI2011]消耗战(虚树DP)

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4998  Solved: 1867[Submit][Statu ...

  6. 【BZOJ2286】【SDOI2011】消耗战 [虚树][树形DP]

    消耗战 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 在一场战争中,战场由n个岛屿和n-1 ...

  7. bzoj2286: [Sdoi2011]消耗战 虚树

    在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望.已知在其他k个 ...

  8. [SDOI2011]消耗战(虚树+树形动规)

    虚树dp 虚树的主要思想: 不遍历没用的的节点以及没用的子树,从而使复杂度降低到\(\sum\limits k\)(k为询问的节点的总数). 所以怎么办: 只把询问节点和其LCA放入询问的数组中. 1 ...

  9. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

随机推荐

  1. VBA 检查模块中是否有某个函数

    Function FindProcedures(ByRef wb As Workbook, ByVal Proc As String) As Boolean    On Error GoTo Exit ...

  2. PHP 生成Word文档

    <?php class word { function start() { ob_start(); echo '<html xmlns:o="urn:schemas-micros ...

  3. 管道限流利器pv

    pv 是什么 可不是 page view,是pipe viewer,管道偷窥器的缩写.这个东西的源站点在google code上,需要的话可以访问pv 的官网 . 这个东西的官方手册页(man pv或 ...

  4. unity 加载读取外部XML

    cfg.xml <rootNode> <category name="网站"> <item name="mainPage"> ...

  5. 在命令提示符下启动并使用JVM时,简单设置堆

    公司电脑内存太小了,只有8G:或者说JVM默认启动占用内存太大了,同时启动多个服务内存就炸了. 比如: java -Xmx128m -Xms64m -Xmn32m -Xss16m -jar eurek ...

  6. bedtools简介及应用

    1)背景处理基因组数据中,比较基因组不同区域,例如寻找overlap等,是一种基本的且常见的问题.虽然UCSC 中‘Table Browser’或者Galaxy可以用来处理,但是当这些工具面对大的数据 ...

  7. java基础六 [异常处理](阅读Head First Java记录)

    在程序运行时,我们不能保证所有服务和方法都是正确的,如果发生问题报错会导致程序崩溃,所以需要对一些可以预见的错误进行异常处理,通过throw去抛出一个异常,然后用try..catch..将要执行的该方 ...

  8. springboot CommandLineRunner

    @SpringBootApplicationpublic class Application implements CommandLineRunner { public static void mai ...

  9. java &&与||短路的详解

    短路运算符就是我们常用的“&&”.“||”,一般称为“条件操作”. class Logic{    public ststic void main(String[] args){    ...

  10. 批量删除进程清理 minerd

    发现顽固minerd 进程与ntp一起启动,所以一起杀掉 yum remove ntp kill -9 `ps -ef | grep ntp|awk '{print $2}'` kill -9 `ps ...