Book of Evil CodeForces - 337D

http://codeforces.com/problemset/problem/337/D

给一棵树 其中有m个点是重要点 一个点到这m给点的距离都小于等于d才算符合条件 问有多少点符合条件

把这m个点想象成m个半径为d的圆 题目就是问有多少点被这m个半径相同的圆全部覆盖 可以想到要求m个点中相距最远的两个点 具体怎么求其实就是树的直径的变形了

一个点要符合条件 肯定要满足最严苛的这两个点 判一下就好

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;

struct node
{
    int v;
    int next;
};

node edge[2*maxn];
int first[maxn],p[maxn],dis1[maxn],dis2[maxn];
int n,m,d,num,p1,p2;

void addedge(int u,int v)
{
    edge[num].v=v;
    edge[num].next=first[u];
    first[u]=num++;
}

void dfs(int *dis,int cur,int fa)
{
    int i,v;
    for(i=first[cur];i!=-1;i=edge[i].next)
    {
        v=edge[i].v;
        if(v!=fa)
        {
            dis[v]=dis[cur]+1;
            dfs(dis,v,cur);
        }
    }
}

int main()
{
    int i,u,v,maxx,ans;
    scanf("%d%d%d",&n,&m,&d);
    for(i=1;i<=m;i++) scanf("%d",&p[i]);
    memset(first,-1,sizeof(first));
    num=0;
    for(i=1;i<=n-1;i++)
    {
        scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    dis1[p[1]]=0;
    dfs(dis1,p[1],0);
    maxx=-1;
    for(i=1;i<=m;i++) if(maxx<dis1[p[i]]) maxx=dis1[p[i]],p1=p[i];
    dis1[p1]=0;
    dfs(dis1,p1,0);
    maxx=-1;
    for(i=1;i<=m;i++) if(maxx<dis1[p[i]]) maxx=dis1[p[i]],p2=p[i];
    dis2[p2]=0;
    dfs(dis2,p2,0);
    /*
    printf("*%d %d*\n",p1,p2);
    for(i=1;i<=n;i++) printf("%d ",dis1[i]);
    printf("\n");
    for(i=1;i<=n;i++) printf("%d ",dis2[i]);
    printf("\n");
    */
    ans=0;
    for(i=1;i<=n;i++)
    {
        if(dis1[i]<=d&&dis2[i]<=d) ans++;
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/82913793