[题解/模板]luogu_P3942_(树上覆盖问题

抄题解

把点按深度排序,用near数组记录到每个点最近的关键点的距离,每次取出一个点更新一下near数组,如果不能被覆盖就在它的k级祖先建立关键点,并更新所有k级祖先的k级祖先的near数组

#include<bits/stdc++.h>
using namespace std;
const int maxn=100009;
int n,k,t,ans;
struct edge{
    int v,nxt;
}e[maxn<<1];
int head[maxn],cnt;
inline void add(int u,int v){
    e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;
}
struct node{
    int dp,id;
    bool operator <(const node&t)const{
        return dp>t.dp;
    }
}p[maxn];
int fa[maxn],nr[maxn];
void pre(int x,int f){
    p[x].dp=p[f].dp+1;fa[x]=f;
    for(int i=head[x];i;i=e[i].nxt){
        if(e[i].v==f)continue;
        pre(e[i].v,x);
    }
}
int main(){
    scanf("%d%d%d",&n,&k,&t);
    for(int i=0;i<=n;i++){
        nr[i]=maxn;p[i].id=i;
    }
    for(int i=1,u,v;i<n;i++){
        scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    pre(1,0);
    sort(p+1,p+1+n);
    for(int i=1;i<=n;i++){
        int x=p[i].id,y=x;
        for(int j=1;j<=k;j++){
            nr[x]=min(nr[x],nr[fa[y]]+j),y=fa[y];
        }
        if(nr[x]>k){
            nr[y]=0;ans++;
            for(int j=1;j<=k;j++){
                nr[fa[y]]=min(nr[fa[y]],j);y=fa[y];
            }
        }
    }
    printf("%d",ans);
}

 

转载于:https://www.cnblogs.com/superminivan/p/11588775.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值