zoukankan      html  css  js  c++  java
  • CodeForces

    题意:一颗树上有且仅有一只恶魔,恶魔会污染距离它小于等于d的点,现在已经知道被污染的m个点,问恶魔在的可能结点的数量。

     容易想到,要是一个点到(距离最远的两个点)的距离都小于等于d,那么这个点就有可能是恶魔所在的点(虽然我也是没有证明凭感觉,逃~~)。

    那么问题就难在怎么快速找到这m个点中距离最远的两个点?我们会想到这跟 找树的直径非常相似,于是就是用找树的直径的方法:树形dp找出这两个点。

    然后距离这两个点的距离都小于等于d的就统计答案即可。

    然后要注意m=1的情况。

    细节请看代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int n,m,d,num,ans,rec,v[N];
    vector<int> G[N];
    
    int d1[N],d2[N],r1[N],r2[N];
    void dfs1(int x,int fa) {
        if (v[x]) d1[x]=0,r1[x]=x;
        for (int i=0;i<G[x].size();i++) {
            int y=G[x][i];
            if (y==fa) continue;
            dfs1(y,x);
            if (d1[y]+1>=d1[x]) {
                d2[x]=d1[x]; r2[x]=r1[x];
                d1[x]=d1[y]+1; r1[x]=r1[y];
            } 
            else if (d1[y]+1>d2[x]) {
                d2[x]=d1[y]+1; r2[x]=r1[y];
            }
        }
        if (d1[x]+d2[x]>ans) {
            ans=d1[x]+d2[x];
            rec=x;
        }
    }
    
    int dep1[N],dep2[N];
    void dfs2(int x,int dd,int fa,int *dep) {
        dep[x]=dd;
        for (int i=0;i<G[x].size();i++) {
            int y=G[x][i];
            if (y==fa) continue;
            dfs2(y,dd+1,x,dep);
        }
    }
    
    int main()
    {
        cin>>n>>m>>d;
        for (int i=1;i<=m;i++) {
            int x; scanf("%d",&x);
            v[x]=1; num=x;
        }
        for (int i=1;i<n;i++) {
            int x,y; scanf("%d%d",&x,&y);
            G[x].push_back(y);
            G[y].push_back(x);
        }
        
        memset(d1,-0x3f,sizeof(d1));
        memset(d2,-0x3f,sizeof(d2));
        ans=0; rec=0;
        dfs1(1,0);
        
        int cnt=0;
        if (m>1) {
            dfs2(r1[rec],0,0,dep1);
            dfs2(r2[rec],0,0,dep2);
            for (int i=1;i<=n;i++)
                if (dep1[i]<=d && dep2[i]<=d) cnt++;
        } else {
            dfs2(num,0,0,dep1);
            for (int i=1;i<=n;i++)
                if (dep1[i]<=d) cnt++;
        }
        cout<<cnt<<endl;
        return 0;
    }
  • 相关阅读:
    POJ 2155:Matrix 二维树状数组
    POJ 2823:Sliding Window 单调队列
    POJ 3007:Organize Your Train part II
    51nod 1208 && POJ 2482:Stars in Your Window
    POJ 3061:Subsequence 查找连续的几个数,使得这几个数的和大于给定的S
    51nod 1206:Picture 求覆盖周长
    POJ 1195:Mobile phones 二维树状数组
    lightoj 1319
    暴力大法好
    Poj1273--Drainage Ditches(最大流)
  • 原文地址:https://www.cnblogs.com/clno1/p/10735903.html
Copyright © 2011-2022 走看看