zoukankan      html  css  js  c++  java
  • 题解 【HEOI2016】tree树

    题面

    解析

    其实这题可以考虑离线做法,用并查集解决。

    因为仔细想,添加标记并不方便,

    但如果用并查集记录下祖先,

    再一一删除,就会方便很多。

    先把每次操作记录下来,

    同时记录下每个点被标记的次数(因为有多次标记,所以不能只用bool)。

    然后dfs遍历,记录祖先。

    再倒序处理,

    当一个点的标记被删完时,就把它的并查集指向它的父亲,

    并统计答案。

    最后输出就行了!

    具体看代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    inline int read(){
        int sum=0,f=1;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
        return f*sum;
    }
    
    struct node{
        int to,next;
    }e[1000001];
    struct hh{
        int fa/*爸爸*/,tag/*标记*/;
        int col/*并查集*/;
    }a[100001];
    struct que{
        int id/*节点*/,opt/*操作*/;
        int ans;
    }qe[100001];
    int head[100001],cnt=0;
    int n,q;
    
    inline void add(int x,int y){
        a[y].fa=x;
        e[++cnt].to=head[x];
        e[cnt].next=y;
        head[x]=cnt;    
    }
    
    int find(int x){
        return a[x].col==x? x:find(a[x].col);
    }
    
    void dfs(int x,int fa){
        a[x].fa=fa;
        if(a[x].tag) a[x].col=x;
        else a[x].col=a[fa].col;
        for(int i=head[x];i;i=e[i].to){
            int k=e[i].next;
            if(k==fa) continue;
            dfs(k,x);
        }
    }
    
    int main(){
    //    freopen("tree.in","r",stdin);
    //    freopen("tree.out","w",stdout);
        n=read();q=read();
        a[1].tag=1;
        for(int i=1;i<n;i++){
            int x=read(),y=read();
            add(x,y);
        }
        for(int i=1;i<=q;i++){
            char opt;
            cin>>opt;
            qe[i].id=read();
            if(opt=='C'){
                qe[i].opt=0;
                a[qe[i].id].tag++;
            }
            else if(opt=='Q'){
                qe[i].opt=1;
            }
        }
        dfs(1,1);
        for(int i=q;i>=1;i--){
            if(!qe[i].opt){
                a[qe[i].id].tag--;
                if(!a[qe[i].id].tag) a[qe[i].id].col=a[a[qe[i].id].fa].col;
            }
            else{
                qe[i].ans=find(a[qe[i].id].col);
            }
        }
        for(int i=1;i<=q;i++){
            if(qe[i].opt){
                printf("%d
    ",qe[i].ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    175. Combine Two Tables
    VirtualBox下安装CentOS7系统
    idea配置maven
    idea配置jdk
    SpringBoot在yml中添加自定义配置并识别
    多表联查另一个表的所有
    java后台判断字符串相等 equals
    查询字段内容截取
    idea刷新项目、清除项目缓存
    SpringBoot集成FreeMarker
  • 原文地址:https://www.cnblogs.com/zsq259/p/10554922.html
Copyright © 2011-2022 走看看