zoukankan      html  css  js  c++  java
  • codeforces 337D 树形DP Book of Evil

    原题直通车: codeforces 337D Book of Evil

    题意:一棵n个结点的树上可能存在一个Evil,Evil危险范围为d,即当某个点与它的距离x<=d时,那么x是危险的。

          现已知道有m个点是危险的,问那个Evil可能存的点有多少。

    分析: 昨晚傻X地暴力提交,自然得到的是TLE。今天看一神的代码才突然明白……

          跟以往的题一样,两个DFS就可求出答案。

          第一个DFS搜出所有危险点,并求出枝干上的点到最远的危险点的距离。

          第二次DFS再往回遍历。具体的参考代码。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    using namespace std;
    const int maxn=111111;
    vector<int>Tree[maxn];
    int deep[maxn];
    int n,m,d,ans;
    bool vis[maxn],vid[maxn];
    void DFS(int cnt){
        vis[cnt]=true;
        deep[cnt]=-1;
        if(vid[cnt]) deep[cnt]=0;
        int len=Tree[cnt].size();
        for(int i=0;i<len;++i){
            int son=Tree[cnt][i];
            if(vis[son]) continue;
            DFS(son);
            deep[cnt]=max(deep[cnt],deep[son]+(deep[son]==-1?0:1));
        }
    }
    void DFS_DP(int cnt,int up){ 
        if(up<=d&&deep[cnt]<=d) ans++;
        vis[cnt]=true;
        int len=Tree[cnt].size();
        vector<int>P,S;
        for(int i=0;i<len;++i) {
            int son=Tree[cnt][i];
            if(vis[son]) continue;
            P.push_back(deep[son]==-1?-1:(deep[son]+2));//兄弟结点-->父亲结点-->自身,所以得+2步
            S.push_back(son);
        }
        int ls=S.size();
        if(ls==0) return;
        vector<int>L(ls),R(ls);
        int Max=-1; //下面两循环是为了求出所有兄弟结点的最大deep值。
        for(int i=0;i<ls;++i){
            L[i]=Max;
            if(P[i]>Max) Max=P[i];
        }
        Max=-1;
        for(int i=ls-1;i>=0;--i){
            R[i]=Max;
            if(P[i]>Max) Max=P[i];
        }
        for(int i=0;i<ls;++i){
            int newup=(up==-1?-1:(up+1));
            newup=max(newup,max(L[i],R[i]));
            if(vid[cnt]&&newup<1) newup=1;
            DFS_DP(S[i],newup);
        }
    }
    int main(){
        cin>>n>>m>>d;
        for(int i=1;i<=m;++i){
            int a; cin>>a; vid[a]=true;
        }
        for(int i=1;i<n;++i) {
            int a,b; cin>>a>>b;
            Tree[a].push_back(b);
            Tree[b].push_back(a);
        }
        DFS(1);
        memset(vis,false,sizeof(vis));
        ans=0;
        DFS_DP(1,-1);
        cout<<ans<<endl;
        return 0;
    }
    



  • 相关阅读:
    java动态代理(JDK和cglib实现对比)
    SynchronizedMap和ConcurrentHashMap 区别
    Spring五个事务隔离级别和七个事务传播行为
    Java 得到磁盘以及内存信息
    java Properties类得到当前的系统属性
    Java Runtime 详解
    java多线程设计模式
    java 得到以后的日期
    apache 配置
    centos7 安装keepalived
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3265355.html
Copyright © 2011-2022 走看看