其他分享
首页 > 其他分享> > 虚树 virtual-tree

虚树 virtual-tree

作者:互联网

我们发现,如果一棵树中真正需要处理的点很少,而总共点数很多时,可以只处理那些需要的点,而忽略其他点。

因此我们可以根据那些需要的点构建虚树,只保留关键点。

oi-wiki上对虚树的介绍

我们根据一下方式建立虚树:

注意:由于整个图需要用到的边与点很少,所以在每次新建虚树的时候不能全局清空,而是在把一个新的点加入栈中的时候清空这个点连过的边。

建立虚树代码:

inline void build()
{
	 sort(query+1,query+m+1,cmp),tot=tp=0;
	 sta[++tp]=1,hea[1]=0;
	 for(int i=1,l;i<=m;i++)
	 {
	 	 if(query[i]==1) continue;
	 	 l=Lca(query[i],sta[tp]);
	 	 if(l!=sta[tp])
	 	 {
	 	 	 while(dfn[l]<dfn[sta[tp-1]])
			 {
			 	 Lca(sta[tp-1],sta[tp]); // 这里用来处理这一条虚树中的边的权值。
				 add(sta[tp-1],sta[tp],minn);
				 tp--;
			 }
	 	 	 if(sta[tp-1]!=l)
			 {
			 	 hea[l]=0;
				 Lca(l,sta[tp]); // 这里用来处理这一条虚树中的边的权值。
				 add(l,sta[tp],minn);
				 sta[tp]=l;
			 }
	 	 	 else
			 {
			 	 Lca(l,sta[tp]); // 这里用来处理这一条虚树中的边的权值。
				 add(l,sta[tp--],minn);
			 }
		 }
		 hea[query[i]]=0,sta[++tp]=query[i];
	 }
	 for(int i=1;i<tp;i++)
	 {
	 	 Lca(sta[i],sta[i+1]); // 这里用来处理这一条虚树中的边的权值。
		 add(sta[i],sta[i+1],minn);
	 }
}

建立完之后就可以在虚树上处理答案了,这样即使多次询问,复杂度也是和选中关键点个数同阶的。

例题:

标签:元素,加入,处理,Lca,tree,virtual,栈中,虚树
来源: https://www.cnblogs.com/EricQian/p/15359399.html