zoukankan      html  css  js  c++  java
  • 虚树

    给定树上一些点集,处理和该点集有关的询问,通常这些询问需要用树形(DP)解决

    若发现所有询问的点集总大小(sum kleqslant 10^5),那么就可以考虑用虚树来解决

    若原树为

    若询问点为(1 2 3),则虚树为

    若询问点为(1 3 7 8),则虚树为

    构造出的虚树为询问点和询问点的(LCA),其他不重要的点和边都进行了类似于路径压缩的操作

    虚树的构建为增量算法,先将每个询问点按(dfs)序排序,用栈来实现,栈内为从根到栈顶元素这条链,这条链同时也是虚树上的链

    实现时,先将根节点入栈

    当要向虚树内插入节点(x)时,分若干情况讨论

    ① 若栈内只有根节点((top=1)),则直接将(x)入栈

    ② 若(lca(x,st[top])=st[top]),说明(x)(st[top])在同一条链上,则

    ③ 若(lca(x,st[top]) e st[top]),则说明(x)(st[top])分别在两棵不同的子树中,这时(st[top])所在的子树已经在虚树上构建完。那么开始退栈,直到将(st[top])所在的子树全部退出栈,同时连虚树上的边,若操作完后(lca)不在栈中,再将其入栈以及连边,最后将(x)入栈

    最后还需将栈清空,将栈内剩余的点进行连边,构建完整个虚树

    (code:)

    bool cmp(const int &a,const int &b)
    {
        return dfn[a]<dfn[b];
    }
    void insert(int x)
    {
        if(x==1) return;
    	if(top==1)
        {
            st[++top]=x;
            return;
        }
        int anc=lca(x,st[top]);
        if(anc==st[top])
        {
            st[++top]=x;
            return;
        }
        while(top>1&&dfn[anc]<=dfn[st[top-1]]) add(st[top-1],st[top]),top--;
        if(anc!=st[top]) add(anc,st[top]),st[top]=anc;
        st[++top]=x;
    }
    
    ......
    
    sort(query+1,query+k+1,cmp);
    st[top=1]=1;
    for(int i=1;i<=k;++i) insert(query[i]);
    while(top) add(st[top-1],st[top]),top--;
    

    注意在树形(DP)后要清空(head),若每次建虚树时(memset),那么就无法保证时间复杂度

    void dp(int x)
    {
        ......
        head[x]=0;
    }
    
  • 相关阅读:
    Ajax
    PS将图标变灰
    圆角
    前端性能优化最佳实践(转)
    jquery $(document).ready() 与window.onload的区别
    js阻止冒泡及jquery阻止事件冒泡示例介绍
    CSS选择器、CSS hack及CSS执行效率
    Github快速入门手册
    Windows 系统下Git安装图解
    史上最全github使用方法:github入门到精通
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229631.html
Copyright © 2011-2022 走看看