CodeForces1065F 树形dp
http://codeforces.com/problemset/problem/1065/F
你有一棵带有n个结点的树,根是结点1。有一个标记,最初在根结点处。你可以将标记移动到其他结点处。假设标记当前所在结点为v,你可以做出以下两种操作: 将标记移动到v子树的任一叶子处。 如果是结点v为叶子,则将标记向根移动不超过 k 次。换句话说,如果 h(v) 为结点 v 的深度 (根的深度为0),你可以将其移动到顶点 to ( to 为 v 祖先) 并且 h(v)−k≤h(to)。 根不是叶子(即使它的度数是 )。计算最多能访问多少叶子。 输入格式: 第一行包含两个整数 n 和 k (<k<n≤^) --- 树中的顶点数和向上移动的限制。 第二行包含 n-1个整数 第i个整数表示结点i+1的父亲 输入保证树合法,根为1。 输出格式: 输出一个整数,表示可以访问的最大叶子数。
题意
把问题想难了,想在树dp上同时用树状数组维护,然后一波操作把自己骚死了
一个显然的贪心思想是从1开始将所有可以拿的结点全部拿完之后返回1,然后进入下一个结点,这样每次遍历到根节点的结果都是最优的,判断拿结点的方法用树dp操作一下,用dfs进行预处理即可。
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
inline int read(){int now=;register char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*+c-'',c=getchar());return now;}
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = 1e6 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
struct Edge{
int to,next;
}edge[maxn * ];
int head[maxn],tot;
void init(){
memset(head,-,sizeof(int) * (N + ));
tot = ;
}
void addedge(int u,int v){
edge[tot].next = head[u];
edge[tot].to = v;
head[u] = tot++;
}
int dp[maxn],dp2[maxn];
void dfs(int t){
if(head[t] == -){
dp[t] = ; dp2[t] = K;
return;
}
dp[t] = ,dp2[t] = ;
for(int i = head[t]; ~i ; i = edge[i].next){
int v = edge[i].to;
dfs(v);
if(dp2[v]) dp[t] += dp[v];
dp2[t] = max(dp2[t],dp2[v] - );
}
}
int sum = ;
void DP(int t,int ans){
if(head[t] == -){
ans++;
sum = max(sum,ans);
}
for(int i = head[t]; ~i; i = edge[i].next){
int v = edge[i].to;
if(dp2[v]){
DP(v,ans + dp[t] - dp[v]);
}else{
DP(v,ans + dp[t]);
}
}
}
int main()
{
Sca2(N,K); init();
for(int i = ; i <= N; i ++){
int u; Sca(u);
addedge(u,i);
}
int root = ;
dfs();
DP(,);
Pri(sum);
#ifdef VSCode
system("pause");
#endif
return ;
}
CodeForces1065F 树形dp的更多相关文章
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- POJ2342 树形dp
原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...
- hdu1561 The more, The Better (树形dp+背包)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...
- bzoj2500: 幸福的道路(树形dp+单调队列)
好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...
随机推荐
- 用于Azure功能的Visual Studio 2017工具
今天我们很高兴地宣布发布第一个预览的Visual Studio 2017工具的Azure功能.这个预览介绍了一些令人兴奋的变化,我们以前的版本.此外,除了支持Visual Studio 2017之外, ...
- luogu2258
题面 sol:先爆搜搜出r行,再在那r行中选c列DP得到最优解 我太菜了,这种题都做了好久,还需锻炼码力啊qwq #include <cstdio> #include <cstrin ...
- Java拦截器
拦截器,主要用于拦截前端请求,常用于登录检查. 下面是演示使用拦截器拦截未登录的用户访问需要登录的模块情景,使用配置方式实现和注解方式实现代码: 配置方式: 1.web.xml中配置监听器,对于所有的 ...
- socket跟TCP/IP 的关系,单台服务器上的并发TCP连接数可以有多少
常识一:文件句柄限制 在Linux下编写网络服务器程序的朋友肯定都知道每一个tcp连接都要占一个文件描述符,一旦这个文件描述符使用完了,新的连接到来返回给我们的错误是"Socket/File ...
- Siki的虚幻第一季
空项目.一闪而过的解决方法 命名空间std::cout的作用: int ,long , long long类型的范围 unsigned int 0-4294967295 int 21474 ...
- HTML条件注释
前面的话 IE条件注释是微软从IE5开始就提供的一种非标准逻辑语句,作用是可以灵活的为不同IE版本浏览器导入不同html元素.很显然这种方法的最大好处就在于属于微软官方给出的兼容解决办法而且还能通过W ...
- JVM深入理解<二>
以下内容来自: http://www.jianshu.com/p/ac7760655d9d JVM相关知识详解 一.Java虚拟机指令集 Java虚拟机指令由一个字节长度的.代表某种特定含义的操作码( ...
- Mining Station on the Sea HDU - 2448(费用流 || 最短路 && hc)
Mining Station on the Sea Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- HAOI2016 简要题解
「HAOI2016」食物链 题意 现在给你 \(n\) 个物种和 \(m\) 条能量流动关系,求其中的食物链条数. \(1 \leq n \leq 100000, 0 \leq m \leq 2000 ...
- 【POJ1704】Georgia and Bob(博弈论)
[POJ1704]Georgia and Bob(博弈论) 题面 POJ Vjudge 题解 这种一列格子中移动棋子的问题一般可以看做成一个阶梯博弈. 将一个棋子向左移动时,它和前面棋子的距离变小,和 ...