[题解/模板]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

时间: 2024-10-24 14:55:18

[题解/模板]luogu_P3942_(树上覆盖问题的相关文章

最新版dlx模板(精确覆盖+重复覆盖)

以前的代码太挫了,重新整理dlx,学习HH把精确覆盖,重复覆盖整合在一起. 代码: struct DLX{ const static int maxn=20010; #define FF(i,A,s) for(int i = A[s];i != s;i = A[i]) int L[maxn],R[maxn],U[maxn],D[maxn]; int size,col[maxn],row[maxn],s[maxn],H[maxn]; bool vis[70]; int ans[maxn],cnt;

P5353 【模板】树上后缀排序

题目地址:[模板]树上后缀排序 我们尝试把普通 SA 改成树上 SA,所以先把普通 SA 贴上来. namespace SA { int sa[N], rk[N], tp[N], tx[N]; inline void tsort() { for (int i = 1; i <= m; i++) tx[i] = 0; for (int i = 1; i <= n; i++) ++tx[rk[i]]; for (int i = 1; i <= m; i++) tx[i] += tx[i-1]

【题解】[CJOI2019] 树上查询(树状数组)

[题解][CJOI2019] 树上查询(树状数组) 题目描述 班?小 A 需要管理信息组的日常纪律.所有人都在树形机房学习,树形机房的根节点为 1 .信息组的同学很多,但树 形机房的每个节点上有且仅有一个同学.小 A 的位置在树形机房的某个节点上,他想要管理在他所站节点子树中的同学(不算自己).每个位置都有一个管理容易值\(w_i\) ,他能管理到某个位置 ,当且仅当他们的距离不超过\(w_i\). 定位一个根\(x\),现在就是求\(u\in S\),\(S\)是\(x\)的所有子树所有节点集

题解 P1034 【矩形覆盖】

题面 在平面上有n个点(n≤50),每个点用一对整数坐标表示.例如:当n=4时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一. 这些点可以用k个矩形(1≤k≤4)全部覆盖,矩形的边平行于坐标轴.当k=2时,可用如图二的两个矩形S1,s2覆盖,81,S2面积和为4.问题是当n个点坐标和k给出后,怎样才能使得覆盖所有点的k个矩形的面积之和为最小呢? 约定:覆盖一个点的矩形面积为0:覆盖平行于坐标轴直线上点的矩形面积也为0.各个矩形必须完全分开(边线与顶点

[题解] LuoguP2764 最小路径覆盖问题

传送门 好久没做网络流方面的题发现自己啥都不会了qwq 题意:给一张有向图,让你用最少的简单路径覆盖所有的点. 考虑这样一个东西,刚开始,我们有\(n\)条路径,每条路径就是单一的一个点,那么我们的目的就是进行若干次操作将路径两两合并,这样对于一个以节点\(x\),它作为路径的端点最多被合并两次(一次连出边一次连入边). 于是考虑二分图,将点\(x\)炸成两个点\(x_0,x_1\),\(x_0\)表示\(x\)连出去的出边,\(x_1\)表示\(x\)连进来的入边.那么对于图上一条\(u \r

BZOJ 1468 Tree 【模板】树上点分治

1 #include<cstdio> 2 #include<algorithm> 3 #define N 50010 4 #define M 500010 5 #define rg register 6 #define LL long long 7 using namespace std; 8 int n,m,cnt,root,tot,totnow,totbf; 9 int last[N],size[N],mxsize[N],dep[N],tmp[N],mg[N]; 10 LL a

[题解/模板]扫描线

luogu_P1856矩形周长 #include<bits/stdc++.h> #define ls (x<<1) #define rs (x<<1|1) //#define mid (l+r>>1) using namespace std; const int maxn=5009; const int maxm=10009; int n,ans; struct square{ int xa,xb,ya,yb; }r[maxn]; int hsh[maxn&

题解【luogu5659 树上的数】

CSP-S2 2019 D1T3 考场上写了2h还是爆零……思维题还是写不来啊 思路分析 最开始可以想到最简单的贪心,从小到大枚举每个数字将其移动到最小的节点.但是通过分析样例后可以发现,一个数字在移动的过程中也可能有无关的边的删除,很难处理.显然直接贪心是不可能的. 分析删边对图的影响.可以发现,一条边删去之后,边两端的部分将不会产生任何影响.也就是说,两边的关系只有这一条边.于是还是之前那个贪心的想法,将边的问题转化为点的问题.现在来分析怎么求解. 具体实现 分析样例后可以发现以下性质: 若

第16章 模板与泛型编程

16.1.1函数模板 //template parameter list template<typename T1,typename T2> int compare(const T1& v1, const T2&v2) { if (v1 < v2) return -1; if (v2 < v1) return 1; return 0; } When we call a function template, the compiler (ordinarily) uses