[CF1065F]Up and Down the Tree_tarjan_树形dp
Up and Down the Tree
题目链接:https://www.luogu.org/problem/CF1065F
数据范围:略。
题解:
我们把每个叶子向它上面$k$个点连边,然后trajan缩点。
表示如果一个$SCC$中的叶子能走到,剩下的就都能。
然后我们就求一个最长的根缀链即可。
代码:
#include <bits/stdc++.h> #define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout) #define N 1000010 using namespace std; char *p1, *p2, buf[100000]; #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ ) int rd() {
int x = 0, f = 1;
char c = nc();
while (c < 48) {
if (c == '-')
f = -1;
c = nc();
}
while (c > 47) {
x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
}
return x * f;
} struct Graph {
int head[N], to[N << 1], nxt[N << 1], tot; inline void add(int x, int y) {
to[ ++ tot] = y;
nxt[tot] = head[x];
head[x] = tot;
}
}G1, G2; int f[21][N]; int dep[N], low[N], cnt, sz[N], F[N], st[N], top, blg[N]; bool vis[N], ins[N]; queue <int> q; void tarjan(int p) {
dep[p] = low[p] = ++cnt;
vis[p] = ins[p] = true;
st[ ++ top] = p;
for (int i = G1.head[p]; i; i = G1.nxt[i]) {
if (!vis[G1.to[i]]) {
tarjan(G1.to[i]), low[p] = min(low[p], low[G1.to[i]]);
}
else if (ins[G1.to[i]]) {
low[p] = min(low[p], dep[G1.to[i]]);
}
}
if (dep[p] == low[p]) {
blg[0] ++ ;
int t;
do {
t = st[top -- ];
blg[t] = blg[0];
ins[t] = false;
} while(t != p);
}
} bool lf[N]; void dfs(int p, int fa) {
f[0][p] = fa;
for (int i = 1; i <= 20; i ++ ) {
f[i][p] = f[i - 1][f[i - 1][p]];
}
for (int i = G1.head[p]; i; i = G1.nxt[i]) {
dfs(G1.to[i], p);
}
} int d[N]; int main() {
// setIO("c");
memset(lf, true, sizeof lf);
int n = rd(), k = rd();
for (int i = 2; i <= n; i ++ ) {
int x = rd();
G1.add(x, i);
lf[x] = false;
}
dfs(1, 1);
for (int i = 2; i <= n; i ++ ) {
if (lf[i]) {
int x = i;
for (int j = 20; ~j; j -- ) {
if (k & (1 << j)) {
x = f[j][x];
}
}
G1.add(i, x);
}
}
tarjan(1);
for (int i = 1; i <= n; i ++ ) {
for (int j = G1.head[i]; j; j = G1.nxt[j]) {
if (blg[i] != blg[G1.to[j]]) {
G2.add(blg[i], blg[G1.to[j]]);
d[blg[G1.to[j]]] ++ ;
}
}
} for (int i = 2; i <= n; i ++ ) {
if (lf[i]) {
sz[blg[i]] ++ ;
}
} for (int i = 1; i <= blg[0]; i ++ ) {
F[i] = sz[i];
} q.push(blg[1]);
while (!q.empty()) {
int x = q.front();
q.pop();
for (int i = G2.head[x]; i; i = G2.nxt[i]) {
F[G2.to[i]] = max(F[x] + sz[G2.to[i]], F[G2.to[i]]);
d[G2.to[i]] -- ;
if (!d[G2.to[i]]) {
q.push(G2.to[i]);
}
}
} int ans = 0;
for (int i = 1; i <= blg[0]; i ++ ) {
ans = max(ans, F[i]);
}
cout << ans << endl ;
// fclose(stdin), fclose(stdout);
return 0;
}
[CF1065F]Up and Down the Tree_tarjan_树形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 ...
随机推荐
- 009_Linux驱动之_request_irq()函数
1. request_irq()函数原型 int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags ...
- Gym - 102307D Do Not Try This Problem
Do Not Try This Problem Gym - 102307D 题意:给个长度为len的字符串(len<=1e5),然后q次操作(q<=1e5),每次给出i,a,k,c,(i ...
- LibreOJ #113. 最大异或和
二次联通门 : LibreOJ #113. 最大异或和 /* LibreOJ #113. 最大异或和 线性基 插入 与 查询最大值 说一下我在学习线性基时遇到的一些问题 1.线性基指的是一个数集 2. ...
- 如何在vue中使用svg
1.安装依赖 npm install svg-sprite-loader --save-dev 2.在config文件中配置 const path = require('path'); func ...
- codeforces gym #101161E - ACM Tax(lca+主席树)
题目链接: http://codeforces.com/gym/101161/attachments 题意: 给出节点数为$n$的树 有$q$次询问,输出$a$节点到$b$节点路程中,经过的边的中位数 ...
- grindtest 测试
性能工程的性能测试 测试的关键趋势之一是将性能测试角色不断转变为成熟的性能工程角色.性能工程现在不仅包括测试方面,还包括监控系统性能.资源的自动伸缩.A/B 测试.ELB.数据库优化.瓶颈识别和监控. ...
- ArcGIS Server“无法创建站点,计算机不具有有效的的许可”
问题描述 ArcGIS Server10.5安装过程中,所有授权和破解均已完成,但是最后一步创建站点的时候显示创建失败,会出现如下图所示的问题:既“无法创建站点,计算机不具有有效的的许可…”,经历了卸 ...
- 访问redis集群提示连接超时的问题
上周在服务器通过docker部署了一个单机版redis集群,今天通过StackExchange.Redis访问的时候报了这个错: 提示我把超时时间设置一下,我去服务器上找到redis的配置文件,发现不 ...
- EntityFramework Core Code First 已有数据库
问题场景:我已经有一个数据库,想用 EF core Code First,怎么办? 首先,可以参考微软的API文档:通过现有数据库在 ASP.NET Core 上开始使用 EF Core, 这一步可以 ...
- vuejs是如何编译checkbox数组的v-model的
随便用官方的例子编译了一下, 发现如下 _c("input", { directives: [ { name: "model", rawName: " ...