zoukankan      html  css  js  c++  java
  • Arab Collegiate Programming Contest 2015 A题 Christmas Tree

    这道题我们发现其实就是单纯的求lca,但是唯一的问题是他有多个点的lca需要求,但是其实只需要求dfs序最大和最小的两个即可,因为dfs表示的是包含的关系。

    本题可以用优先队列保存大小值也可以用set来维护

    #include<iostream>
    #include<queue>
    #include<map>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    #include<stack>
    #include<string>
    #include<cstring>
    #include<set>
    #define P pair<int,int>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    int cnt[N];
    int h[N],ne[N],e[N],fa[N][17],idx;
    int depth[N],num[N];
    int rnum[N];
    bool vis[N];
    set<int> ask;
    void add(int a,int b){
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    void bfs(){
        memset(depth,0x3f,sizeof depth);
        depth[0]=0,depth[1]=1;
        queue<int> q;
        q.push(1);
        while(q.size()){
            int t=q.front();
            q.pop();
            int i;
            for(i=h[t];i!=-1;i=ne[i]){
                int j=e[i];
                if(depth[j]>depth[t]+1){
                    depth[j]=depth[t]+1;
                    q.push(j);
                    fa[j][0]=t;
                    for(int k=1;k<=16;k++){
                        fa[j][k]=fa[fa[j][k-1]][k-1];
                    }
                }
            }
        }
    }
    int tot=0;
    void dfs(int u,int root){
        num[u]=++tot;
        rnum[tot]=u;
        int i;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==root)
                continue;
            dfs(j,u);
        }
    }
    int lca(int a,int b){
        if(depth[a]<depth[b])
            swap(a,b);
        int i;
        for(i=16;i>=0;i--){
            if(depth[fa[a][i]]>=depth[b])
                a=fa[a][i];
        }
        if(a==b)
            return a;
        for(i=16;i>=0;i--){
            if(fa[a][i]!=fa[b][i]){
                a=fa[a][i];
                b=fa[b][i];
            }
        }
        return fa[a][0];
    }
    int main(){
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            tot=0;
            ask.clear();
            idx=0;
            int i;
            memset(h,-1,sizeof h);
            memset(num,0,sizeof num);
            memset(rnum,0,sizeof rnum);
            memset(fa,0,sizeof fa);
            for(i=0;i<n-1;i++){
                int u,v;
                scanf("%d%d",&u,&v);
                u++;
                v++;
                add(u,v);
                add(v,u);
            }
            bfs();
            dfs(1,-1);
            int m;
            cin>>m;
            for(i=0;i<m;i++){
                char s[2];
                scanf("%s",s);
                int x;
                scanf("%d",&x);
                if(s[0]=='+'){
                    x++;
                    ask.insert(num[x]);
                    int a=*ask.begin();
                    auto it=ask.end();
                    int b=*(--it);
                    int d=lca(rnum[a],rnum[b]);
                    printf("%d
    ",--d);
                }
                else{
                    x++;
                    ask.erase(num[x]);
                    if(!ask.size()){
                        printf("-1
    ");
                        continue;
                    }
                    int a=*ask.begin();
                    auto it=ask.end();
                    int b=*(--it);
                    int d=lca(rnum[a],rnum[b]);
                    printf("%d
    ",--d);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    elasticsearch常用命令
    logstash向elasticsearch写入数据,如何指定多个数据template
    rsync 实现文件同步 (重要数据通过rsyncr把数据同步到不同的两台服务器上,这样可以防止服务器的硬盘故障导致数据丢失) 客户端同步时如果要排某个目录
    rdesktop 指定服务器的分频率
    /etc/sudoers 配置
    su 和 su
    rdesktop 源码安装
    通过show variables like ‘general_log%’可以看查询日志
    密钥登陆服务器 失败
    log_output参数是指定日志的存储方式
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12529580.html
Copyright © 2011-2022 走看看