• SDOI2015寻宝游戏 dfs序+set


    SDOI2015寻宝游戏

    好像是一道虚树入门题?

    虚树???不会不会我弱死了。。

    Solution:

    关键点间的最小路径,就是在保证尽量少走重复路的前提下走出来的一条经过所有关键点的路径。

    基于这个思想,我们思考怎样走出来的会是重复最少的呢???

    不妨想一想dfs,我们dfs时就是保证了每个点只遍历一次,每条边只遍历了两次,这已经是最优的情况了!!

    所以,对于这些关键点,把它们按照dfs序遍历,可以发现路径就是最小的。

    对于修改,我们相当于只要维护了关键点dfs序,就只要对应的在序列上插入、删除就好了,用set即可。

    说实话,本人运用set等STL的能力极差,所以每每遇到这种需要set等的题,就会。。。enenen

    Code↓:

    #include<set>
    #include<cmath>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define RG register
    #define IL inline
    #define LL long long
    #define DB double 
    using namespace std;
    
    IL int gi() {
        char ch=getchar(); RG int x=0,q=0;
        while(ch<'0'||ch>'9') q=ch=='-'?1:q,ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return q?-x:x;
    }
    
    const int N=1e5+10;
    
    set<int> seq;
    set<int>::iterator IT,pr,sf;
    
    LL ans,dis[N];
    int n,m,Time,tot,head[N],mp[N],dep[N],dfn[N],dot[N],f[N][21];
    
    struct EDGE{int next,to,ver;}e[N<<1];
    IL void make(int a,int b,int c) {
        e[++tot]=(EDGE){head[a],b,c},head[a]=tot;
        e[++tot]=(EDGE){head[b],a,c},head[b]=tot;
    }
    
    void dfs(int x,int fx) {
        RG int i,y;
        dfn[x]=++Time,mp[Time]=x;
        for (i=head[x],dep[x]=dep[fx]+1;i;i=e[i].next)
            if ((y=e[i].to)!=fx) f[y][0]=x,dis[y]=dis[x]+e[i].ver,dfs(y,x); 
    }
    
    IL void getf() {
        RG int i,j;
        for (i=1;i<=18;++i)
            for (j=1;j<=n;++j)
                f[j][i]=f[f[j][i-1]][i-1];
    }
    
    IL void Find(int x) {
        IT=seq.lower_bound(dfn[x]);
        if (IT==seq.begin()) pr=seq.end(),pr--;
        else pr=IT,pr--;
        sf=IT,sf++;
        if (sf==seq.end()) sf=seq.begin();
    }
    
    IL int Lca(int x,int y) {
        RG int i;
        if (dep[x]<dep[y]) swap(x,y);
     	for (i=18;i>=0;--i)
            if (dep[f[x][i]]>=dep[y]) x=f[x][i];
        if (x==y) return x;
        for (i=18;i>=0;--i)
            if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    
    IL LL Path(int x,int y) {return dis[x]+dis[y]-2*dis[Lca(x,y)];}
    
    int main ()
    {
        RG int i,x,y,z,pre=0,suf=0;
        n=gi(),m=gi();
        for (i=1;i<n;++i) x=gi(),y=gi(),z=gi(),make(x,y,z);
        for (i=1,dfs(1,0),getf();i<=m;++i) {
            dot[x=gi()]^=1;
            if (dot[x]) {
                seq.insert(dfn[x]),Find(x);
                suf=mp[*sf],pre=mp[*pr];
                ans+=Path(pre,x)+Path(x,suf)-Path(pre,suf);
            }
            else {
                Find(x),seq.erase(dfn[x]);
                suf=mp[*sf],pre=mp[*pr];
                ans+=Path(pre,suf)-Path(pre,x)-Path(x,suf);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
    

    The End

  • 相关阅读:
    细菌(disease)
    素数路(prime)
    母亲的牛奶(milk)
    Counting Islands II
    Popular Products
    Binary Watch
    BZOJ 1822[JSOI2010]Frozen Nova 冷冻波
    尝试一下LLJ大佬的理论AC大法
    BZOJ 3626 [LNOI2014]LCA
    BZOJ 3319 黑白树
  • 原文地址:https://www.cnblogs.com/Bhllx/p/10616998.html
Copyright © 2020-2023  润新知