zoukankan      html  css  js  c++  java
  • 【BZOJ 4551】【TJOI2016】【HEOI2016】树

    http://www.lydsy.com/JudgeOnline/problem.php?id=4551

    题目描述

    给定一棵有根树(根为 1),有以下两种操作:
    1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个结点,可以打多次标记。)
    2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖先)。

    输入格式

    输入第一行两个正整数 NQ 分别表示节点个数和操作次数
    接下来 N-1 行,每行两个正整数 u,v (1$leq$u,v$leq$n) 表示 uv 有一条有向边
    接下来 Q 行,“ C ”时表示这是一个标记操作,为“ Q ”时表示这是一个询问操作,

    输出格式

    对于每一个询问操作,输出一个正整数,表示结果。

    输入样例

    5 5
    1 2
    1 3
    2 4
    2 5
    Q 2
    C 2
    Q 2
    Q 5
    Q 3

    输出样例

    1
    2
    2
    1

    数据范围

    1$leq$N,Q$leq$10^5

     

    题解

    初始时打好所有标记,逆序处理,用并查集维护,当遇到一个询问操作时,把标记 -1 ,若此时标记变为 0 ,则将该点与父亲节点合并。

     

     

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define N 1500005
    #define depth 32
    using namespace std;
    int n,q,tot;
    struct hh
    {int to,next;}e[N<<1];
    int fa[N],dep[N],col[N],last[N],f[N],opt[N],x[N],ans[N];
    void add(int a,int b)
    {
        e[++tot].to=b;
        e[tot].next=last[a];
        last[a]=tot;
    }
    void dfs(int now)
    {
        int i;
        for(i=last[now];i;i=e[i].next)
            if(!dep[e[i].to])
            {
                dep[e[i].to]=dep[now]+1;
                fa[e[i].to]=now; 
                dfs(e[i].to);
            }
    }
    int read()
    {
        int ret=0;char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)){
            ret=(ret<<1)+(ret<<3)+c-'0';
            c=getchar();
        }
        return ret;
    }
    int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
    int main()
    {
        int i,j,u,v,fx,fy;
        char flag;
        n=read();q=read();
        for(i=1;i<=n-1;i++)
        {
            u=read();v=read();
            add(u,v); add(v,u);
        }
        dfs(1);
        for(i=1;i<=q;i++)
        {
            scanf("
    %c",&flag);
            if(flag=='C') opt[i]=1;
            else opt[i]=2;
            x[i]=read();
        }
        dep[1]=1;col[1]=1;
        for(i=1;i<=q;i++)
            if(opt[i]==1) col[x[i]]++;
        for(i=1;i<=n;i++) f[i]=i;
        for(i=2;i<=n;i++)
            if(!col[i]) f[find(i)]=find(fa[i]);
        for(i=q;i>=1;i--)
            if(opt[i]==2) ans[++ans[0]]=find(x[i]);
            else
            {
                col[x[i]]--;
                if(!col[x[i]]) f[find(x[i])]=find(fa[x[i]]);
            }
        for(i=ans[0];i>=1;i--)
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    工业互联网兴起
    互联网经济学
    广泛应用的区块链技术
    工业互联网数据传输探讨
    谈谈网站性能
    深入探讨vue响应式原理
    工业互联网虚拟数字
    对www.518shengmao.com站资源打包,采用vue Node.js
    jquery的事件命名空间详解
    巧用索引与变量
  • 原文地址:https://www.cnblogs.com/yljiang/p/6034090.html
Copyright © 2011-2022 走看看