只看45分的话,是树形DP....(当然也有能拿到70分+的大佬)

40分:

只考虑k==1的情况,树形DP

所以每个节点可能被父亲,自己,儿子控制

设f[MAXN][3],0表示儿子,1表示自己,2表示父亲

f[i][1]+=min(f[to][0],f[to][1],f[to][2])(因为自己控制自己,儿子怎样都行)

f[i][0]+=min(f[to][0],f[to][1])

但是因为i的儿子必须有一个自己控制自己,所以还要判断所加值中是否有f[to][1],如果没有

f[i][0]+=min(f[to][1]-f[to][0])

f[i][2]+=min(f[to][1],f[to][0])

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<string>
5 #include<map>
6 #include<vector>
7 #include<set>
8 #include<cmath>
9 #define MAXN 600001
10 #define int long long
11 using namespace std;
12 struct node{int to,n;}e[MAXN*2];
13 int head[MAXN],tot;
14 void add(int u,int v)
15 {
16 e[++tot].to=v;e[tot].n=head[u];head[u]=tot;
17 }
18 int read()
19 {
20 int x=0;char c=getchar();
21 while(c<'0'||c>'9')c=getchar();
22 while(c>='0'&&c<='9')
23 {
24 x=(x<<1)+(x<<3)+(c^48);
25 c=getchar();
26 }
27 return x;
28 }
29 int f[MAXN][4];//0 儿子 1 自己 2 父亲
30 void DFS(int x,int fa)
31 {
32 int ok=1,minn=100000;
33 f[x][1]=1;
34 for(int i=head[x];i;i=e[i].n)
35 {
36 int to=e[i].to;
37 if(to==fa)continue;
38 DFS(to,x);
39 if(f[to][1]<=f[to][0])
40 {
41 f[x][0]+=f[to][1];
42 ok=0;
43 }
44 else f[x][0]+=f[to][0];
45 f[x][1]+=min(f[to][1],min(f[to][2],f[to][0]));
46 f[x][2]+=min(f[to][1],f[to][0]);
47 }
48 if(ok==1)
49 {
50 for(int i=head[x];i;i=e[i].n)
51 {
52 int to=e[i].to;
53 if(to==fa)continue;
54 minn=min(minn,f[to][1]-f[to][0]);
55 }
56 f[x][0]+=minn;
57 }
58 }
59 int n,k,t;
60 signed main()
61 {
62 n=read();k=read();t=read();
63 for(int i=1;i<=n-1;++i)
64 {
65 int x,y;
66 x=read();y=read();
67 add(x,y);add(y,x);
68 }
69 if(k==0)
70 {
71 printf("%lld\n",n);
72 return 0;
73 }
74 DFS(1,0);
75 printf("%lld\n",min(f[1][1],f[1][0]));
76 }

45分

100分

贪心很好想吧.....

每次选出深度最大的节点,找到他的第k级祖先,然后暴力修改他的k距离范围内的点

正确性的话,我们每次恰好选k级祖先(或根),对于覆盖范围来说,肯定比k级祖先的父亲和儿子要好啦啦.....

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<string>
5 #include<map>
6 #include<vector>
7 #include<set>
8 #include<algorithm>
9 #include<cmath>
10 #include<queue>
11 #define MAXN 1000001
12 using namespace std;
13 struct node{int to,n;}e[MAXN*2];
14 int n,k,t;
15 int head[MAXN],tot=0;
16 int read()
17 {
18 char c=getchar();int x=0;
19 while(c<'0'||c>'9')c=getchar();
20 while(c>='0'&&c<='9')
21 {
22 x=(x<<1)+(x<<3)+(c^48);
23 c=getchar();
24 }
25 return x;
26 }
27 void add(int u,int v)
28 {
29 e[++tot].to=v;e[tot].n=head[u];head[u]=tot;
30 }
31 priority_queue<pair<int,int> >q;
32 int fa[MAXN];
33 int deep[MAXN];
34 void DFS(int x,int faa)
35 {
36 q.push(make_pair(deep[x],x));
37 for(int i=head[x];i;i=e[i].n)
38 {
39 int to=e[i].to;
40 if(faa==to)continue;
41 fa[to]=x;
42 deep[to]=deep[x]+1;
43 DFS(to,x);
44 }
45 }
46 bool vis[MAXN];
47 int find(int x,int kk)
48 {
49 if(deep[x]<=kk)return 1;
50 while(kk!=0)
51 {
52 kk--;
53 x=fa[x];
54 }
55 return x;
56 }
57 void check(int x,int faa,int root,int kx)
58 {
59 if(kx>k)return ;
60 vis[x]=1;
61 //printf("vis[%d]=%d deep[%d]=%d\n",x,vis[x],root,deep[root]);
62 for(int i=head[x];i;i=e[i].n)
63 {
64 int to=e[i].to;
65 if(to==faa)continue;
66 check(to,x,root,kx+1);
67 }
68 return ;
69 }
70 int ans=0;
71 void work()
72 {
73 while(!q.empty())
74 {
75 int top=q.top().second;
76 //printf("top=%d\n",top);
77 q.pop();
78 if(vis[top]==1)continue;
79 int faa=find(top,k);
80 //printf("faa=%d\n",faa);
81 check(faa,0,faa,0);
82 ans++;
83 }
84 }
85 signed main()
86 {
87 n=read();k=read();t=read();
88 for(int i=1;i<=n-1;++i)
89 {
90 int x,y;
91 x=read();y=read();
92 add(x,y);add(y,x);
93 }
94 deep[1]=1;
95 DFS(1,0);
96 work();
97 printf("%d\n",ans);
98 }

还有要注意的一点,在找与祖先相邻为k的点时暴力查找,不看深度。。。。

【模拟8.11】将军令(贪心&&树形DP)的更多相关文章

  1. bzoj 1907: 树的路径覆盖【贪心+树形dp】

    我是在在做网络流最小路径覆盖的时候找到这道题的 然后发现是个贪心+树形dp \( f[i] \)表示在\( i \)为根的子树中最少有几条链,\( v[i] \) 表示在\( i \)为根的子树中\( ...

  2. 联赛模拟测试25 C. Repulsed 贪心+树形DP

    题目描述 分析 考虑自底向上贪心 \(f[x][k]\) 表示 \(x\) 下面距离为 \(k\) 的需要灭火器的房间数,\(g[x][k]\) 表示 \(x\) 下面距离为 \(k\) 的多余灭火器 ...

  3. [JZOJ5400]:Repulsed(贪心+树形DP)

    题目描述 小$w$心里的火焰就要被熄灭了. 简便起见,假设小$w$的内心是一棵$n-1$条边,$n$个节点的树. 现在你要在每个节点里放一些个灭火器,每个节点可以放任意多个. 接下来每个节点都要被分配 ...

  4. BZOJ 4027:[HEOI2015]兔子与樱花(贪心+树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4027 [题目大意] 樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1 ...

  5. codehunter 「Adera 6」杯省选模拟赛 网络升级 【树形dp】

    直接抄ppt好了--来自lyd 注意只用对根判断是否哟留下儿子 #include<iostream> #include<cstdio> using namespace std; ...

  6. BZOJ4849[Neerc2016]Mole Tunnels——模拟费用流+树形DP

    题目描述 鼹鼠们在底下开凿了n个洞,由n-1条隧道连接,对于任意的i>1,第i个洞都会和第i/2(取下整)个洞间有一条隧 道,第i个洞内还有ci个食物能供最多ci只鼹鼠吃.一共有m只鼹鼠,第i只 ...

  7. P2279 [HNOI2003]消防局的设立 贪心or树形dp

    题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状 ...

  8. CF 463A && 463B 贪心 && 463C 霍夫曼树 && 463D 树形dp && 463E 线段树

    http://codeforces.com/contest/462 A:Appleman and Easy Task 要求是否全部的字符都挨着偶数个'o' #include <cstdio> ...

  9. 【bzoj4027】[HEOI2015]兔子与樱花 树形dp+贪心

    题目描述 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它 ...

随机推荐

  1. PHP逐行解析文件,并写入数据库

    $filePath为文件路径,上传文件则返回文件路径调用下面函数即可public function readText($filePath,&$errorCode,&$errorMess ...

  2. 如何使用java搭建一款高性能的Mqtt集群broker!

    SMQTT是一款开源的MQTT消息代理Broker, SMQTT基于Netty开发,底层采用Reactor3反应堆模型,支持单机部署,支持容器化部署,具备低延迟,高吞吐量,支持百万TCP连接,同时支持 ...

  3. 5分钟,教你用Python每天跟女朋友说1000遍土味情话!

  4. 小程序中支持es7的async语法

    小程序中支持es7的async语法 es7的 async 号称是解决回调的最终⽅案 在⼩程序的开发⼯具中,勾选 es6转es5语法 下载 facebook的regenerator库中的 在⼩程序⽬录下 ...

  5. 腾讯暑期 前后七面 + hr(已拿offer面经)

    以下是时间线 魔方 魔术师工作室 3.19 一面(120mins) c++ struct和union区别? 指针和引用的区别? 左值和右值? 字节对齐的作用? 什么情况下需要自定义new? mallo ...

  6. Masm32sdk安装指南

    上一年学习win32汇编时用的masm32sdk不是最新版本的.因为最近准备继续学习win32汇编,所以准备安装最新的masm32sdk软件包.其中遇到了一些问题,从网上找了2个小时才搞定(宝宝心里苦 ...

  7. 爬虫:获取动态加载数据(selenium)(某站)

    如果网站数据是动态加载,需要不停往下拉进度条才能显示数据,用selenium模拟浏览器下拉进度条可以实现动态数据的抓取. 本文希望找到某乎某话题下讨论较多的问题,以此再寻找每一问题涉及的话题关键词(侵 ...

  8. 技术博客:Azure Functions + Azure Storage 开发

    Azure GitHub wiki 同步发布 传送门 Azure Functions 通过 Functions(一个事件驱动型无服务器计算平台,还可以解决复杂的业务流程问题)更加高效地进行开发.在本地 ...

  9. [bug] Unrecognized token 'code': was expecting (JSON String, Number, Array, Object,'true', 'false' or 'null')

    JSON格式有误,需用JSON.stringify()函数转换一下 参考 https://www.cnblogs.com/sunyanblog/p/13788740.html https://www. ...

  10. [刷题] 447 Number of Boomerangs

    要求 给出平面上n个点,寻找存在多少点构成的三元组(i j k),使得 i j 两点的距离等于 i k 两点的距离 n 最多为500,所有点坐标范围在[-10000, 10000]之间 示例 [[0, ...