算法 | 虚树学习笔记

虚树学习笔记?

blog

  • 虚树是一棵虚拟构建的树…废话 这棵树只包含关键点和关键的点,而其他不影响虚树结构的点和边都相当于进行了路径压缩…而且整棵虚树的大小不会超过关键点的2倍

    • 举个例子?
    • 比方说…4 5 6 7 表示关键点(现在你要让这些关键点也形成一棵树…要求点最少但不能破坏原来树的结构)
    • 构建完的虚树长这个样(其实这也是构建虚树时候的最坏情况…所有原来树上的点都加入了虚树之中)
    • 什么时候才会出现这种最坏的情况???当所有叶子节点都是关键点的时候…,但是很显然的是叶子结点不会超过 n 2 \dfrac{n}{2} 2n
  • 如何构建虚树?

    • 预处理出dfs序…将关键点按照dfs序进行排序

    • 我们使用一个,从栈顶到栈底的元素形成虚树的一条树链.

    • Code

      • 	sort(af + 1, af + 1 + num, cmp);
        	if(con[1] != 1) st[++top] = 1;
        	for(int i = 1; i <= num; ++i) {
                 
        		int pos = af[i], fa = 0;
        		for(; top;) {
                 
        			fa = GetLCA(st[top], pos);
        			if(top > 1 && dep[fa] < dep[st[top - 1]]) {
                 
        				add(st[top - 1], st[top]), top--;
        			} else if(dep[fa] < dep[st[top]]) {
                 
        				add(fa, st[top]), top--;
        				break;
        			} else {
                 
        				break;
        			}
        		}
        		if(st[top] != fa) 
        			st[++top] = fa;
        		st[++top] = pos;
        	}
        	for(; top > 1; --top)
        		add(st[top - 1], st[top]);
        
  • 正确性✅?

    • 对于任意指定两点 a , b a,b a,b l c a lca lca ,都存在 d f s dfs dfs 序连续的两点 u , v u,v u,v( d f n [ u ] ≤ d f n [ v ] dfn[u]\leq dfn[v] dfn[u]dfn[v]) 分别属于 l c a lca lca包含 a , b a,b a,b 的两棵子树,此时这 v v v 加入时按照上面的操作必定会把 l c a lca lca加入栈,所以应当加入的点都加入了。对于非 l c a lca lca 点,按照上面操作是不会出现这个点的。
HDU6035 Colorful tree
  • 题意:

    • 给你一棵 n ( 1 ≤ n ≤ 200000 ) n(1\leq n\leq 200000) n(1n200000)个节点的树…每一个节点有一个颜色.一条路径的权值定义为出现颜色集合的大小…问所有路径的权值和是多少…
  • 题解:

    当我们在考虑这个问题怎么求的时候…我们很容易地考虑到要计算每个颜色的贡献

    我们会发现这样正着做会很难…遇难则反

    • 问题转换为求有多少条路径没有出现过颜色 c c c

    事实上我们并不需要构建出每一种颜色的虚树… 只需一遍dfs就可以考虑啦!

    但是应用到了虚树的思想…

    首先一个颜色没有 c o l col col的联通块里任意两个点的路径上都不会出现 c o l col col这个颜色

    我们记录一个 s u m [ x ] sum[x] sum[x]表示遍历到当前这个点 颜色为 x x

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值