zoukankan      html  css  js  c++  java
  • UVA 1357 Cells

    考虑一颗普通的树,DFS一遍后得到每个点的DFS前序历遍顺序值dfsid[] ,和以改点为根的子树的总结点数num[]。

    (比如第一组样例dfsid[]={0,1,6,8,2,3,7,9,4,5}   num[]={10,5,2,2,1,3,1,1,1,1});

    那么要判断a是否为b的祖先,只要满足dfsid[a]<dfsid[b]<dfsid[a]+num[a]

    因为这题的结点最多会有2000W,所以不能建完整的树,只能建n个结点,否则超时。

    由于编号大于n的结点肯定是叶节点,我们可以通过求son数组(每个结点的儿子数)的前缀和,然后二分查找找到b的父亲结点,再判断。

    大概步骤就是

    1.BFS建树,只建n个结点。

    2.DFS,求dfsid[] 和num[] 数据量大,用栈模拟递归

    3.求son[]的前缀和

    4.判断每对a,b.     会有a==b的数据

    总复杂度O(mlogn)

    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<cmath>
    #include<climits>
    #include<string>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    #define pb(a) push(a)
    #define INF 0x1f1f1f1f
    #define lson idx<<1,l,mid
    #define rson idx<<1|1,mid+1,r
    #define PI  3.1415926535898
    template<class T> T min(const T& a,const T& b,const T& c) {
        return min(min(a,b),min(a,c));
    }
    template<class T> T max(const T& a,const T& b,const T& c) {
        return max(max(a,b),max(a,c));
    }
    void debug() {
    #ifdef ONLINE_JUDGE
    #else
    
        freopen("d:\in1.txt","r",stdin);
        freopen("d:\out1.txt","w",stdout);
    #endif
    }
    int getch() {
        int ch;
        while((ch=getchar())!=EOF) {
            if(ch!=' '&&ch!='
    ')return ch;
        }
        return EOF;
    }
    
    const int maxn=300200;
    vector<int> g[maxn];
    int n;
    int son[maxn];
    int dfsid[maxn];
    int num[maxn];
    
    struct stacknode
    {
        int u,i;
    };
    int dfs()
    {
        int dfs_clock=0;
        stack<stacknode> st;
        st.push((stacknode){0,0});
        while(!st.empty())
    
        {
            stacknode x=st.top();st.pop();
            if(x.i==0){num[x.u]=1;dfsid[x.u]=dfs_clock++;}
            if(x.i<g[x.u].size())
            {
                x.i++;
                st.push(x);
                st.push((stacknode){g[x.u][x.i-1],0});
            }else
            {
                for(int i=0;i<g[x.u].size();i++)
                    num[x.u]+=num[g[x.u][i]];
            }
        }
    }
    void build()
    {
        int num=1;
        queue<int> q;
        q.push(0);
        while(!q.empty())
        {
            int x=q.front();q.pop();
            g[x].clear();
            if(x==n-1)return ;
            if(num>=n)continue;
            for(int i=1;i<=son[x];i++)
            {
                g[x].push_back(num);
                q.push(num++);
                if(num>=n)break;
            }
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        for(int ca=1;ca<=t;ca++)
        {
            scanf("%d",&n);
            for(int i=0;i<n;i++)
                scanf("%d",&son[i]);
            build();
            dfs();
            for(int i=1;i<n;i++)
                son[i]+=son[i-1];
            int m;
            scanf("%d",&m);
            printf("Case %d:
    ",ca);
            for(int i=1;i<=m;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                if(a==b)
                {
                    printf("No
    ");continue;
                }
                if(b>=n)
                    b=lower_bound(son,son+n,b)-son;
                if(a<n&&dfsid[a]+num[a]>dfsid[b]&&dfsid[b]>=dfsid[a])
                    printf("Yes
    ");
                else printf("No
    ");
            }
            if(ca!=t)printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    内存泄漏 Memory Leaks 内存优化 MD
    Handler Thread 内部类引起内存泄露分析
    为什么不取消注册BroadcastReceiver会导致内存泄漏
    WebChromeClient 简介 API 案例
    WebViewClient 简介 API 案例
    java.net.URI 简介 文档 API
    android.net.Uri 简介 API
    RV 多样式 MultiType 聊天界面 消息类型 MD
    JS函数声明与定义,作用域,函数声明与表达式的区别
    CSS中table tr:nth-child(even)改变tr背景颜色: IE7,8无效
  • 原文地址:https://www.cnblogs.com/BMan/p/3619873.html
Copyright © 2011-2022 走看看