zoukankan      html  css  js  c++  java
  • codeforce 337D Book of Evil ----树形DP&bfs&树的直径

    比较经典的老题

    题目意思:给你一颗节点数为n的树,然后其中m个特殊点,再给你一个值d,问你在树中有多少个点到这m个点的距离都不大于d。

    这题的写法有点像树的直径求法,先随便选择一个点(姑且设为点1)来遍历一遍树,存下所有点到点1的距离。然后在m个特殊点中找到距离点1最远的点a1.

    然后以a1为初始点遍历一遍树,求每一个点到a1的距离,存在dp[i]中。并且再在m个点中找到到a1距离最大的点a2.最后再以a2为初始点遍历一遍树,求到每一个点到a2的距离dp1[i]。然后for遍历所有点,如果dp[i]和dp1[i]都不大于d,那么合法解+1;

    这里可以做一个小证明,如果一个点k还能在m个特殊点中找到距离大于到a1和到a2距离的点s的话,那么点k到a1的距离加上点k到s的距离将大于k到a1加上k到a2,那么在第二次搜索中搜到的距离a1最远的点就不应该是a2而是s,所以不成立。由此反证得知。

    具体代码如下:

    #include<iostream>
    #include<vector>
    #include<queue>
    #include<string.h>
    using namespace std;
    bool pd[100050];
    int dp[100050],dp1[100050];
    int dd[100050];
    vector<int> a[100050];
    int bfs(int u)
    {
        memset(pd,false,sizeof(pd));
        memset(dp,0,sizeof(dp));
        pd[u]=1;
        queue<int> q;
        q.push(u);
        while(q.size()!=0)
        {
            int t=q.front();
            q.pop();
            for(int i=0;i<a[t].size();i++)
            {
                int v=a[t][i];
                if(pd[v]) continue;
                //cout<<"w="<<w<<endl;
                
                pd[v]=1;
                dp[v]=dp[t]+1;
                q.push(v);
            }
        }
        return 1;
    }
    int bfs1(int u)
    {
        memset(pd,false,sizeof(pd));
        memset(dp1,0,sizeof(dp1));
        pd[u]=1;
        queue<int> q;
        q.push(u);
        while(q.size()!=0)
        {
            int t=q.front();
            q.pop();
            for(int i=0;i<a[t].size();i++)
            {
                int v=a[t][i];
                if(pd[v]) continue;
                //cout<<"w="<<w<<endl;
                
                pd[v]=1;
                dp1[v]=dp1[t]+1;
                q.push(v);
            }
        }
        return 1;
    }
    int main()
    {
        int i,j,k,l,x,y,n,m,d;
        scanf("%d%d%d",&n,&m,&d);
       // cout<<n<<" "<<m<<" "<<d<<endl;
        for(i=0;i<m;i++) scanf("%d",&dd[i]);
        for(i=0;i<n-1;i++) 
        {
            scanf("%d%d",&x,&y);
            a[x].push_back(y);
            a[y].push_back(x);
        }
        bfs(1);
        int lon=0,a1=1;
        for(i=0;i<m;i++) 
        if(dp[dd[i]]>lon)
        {
            lon=dp[dd[i]];
            a1=dd[i];
        }
        //cout<<lon<<"。。"<<a1<<endl; 
        bfs(a1);
        lon=0;
        for(i=0;i<m;i++) 
        if(dp[dd[i]]>lon)
        {
            lon=dp[dd[i]];
            a1=dd[i];
        }
        //cout<<lon<<"。。"<<a1<<endl; 
        int ans=0;
        bfs1(a1);
        for(i=1;i<=n;i++)
        {
            if(dp[i]<=d&&dp1[i]<=d) ans++;
        }
        //for(i=1;i<=n;i++) cout<<dp[i]<<" "<<dp1[i]<<endl;
        printf("%d
    ",ans);
    }
  • 相关阅读:
    python第三十二课——队列
    python第三十二课——栈
    python提示警告InsecureRequestWarning
    关于requests.exceptions.SSLError: HTTPSConnectionPool
    python第三十一课--递归(3.递归的弊端)
    01 redis特点及安装使用
    22 nginx配置与集群
    21-nginx单机1W并发优化
    20-ab压力测试及nginx性能统计模块
    19 大网站的优化思路
  • 原文地址:https://www.cnblogs.com/wsblm/p/10726720.html
Copyright © 2011-2022 走看看