HDU 6203 ping ping ping 最近公共祖先 树状数组
题意
- 给我们一棵n+1节点,n条边的树,然后给我们p条路径(每条路径给出两个端点)。我们需要从树上选出一些点,使得每条路径都至少包含我们选出的一个点。求最少选多少点。
思路
- 以1为根,我们可以发现如果两条路径相交,设两条路径两端点的LCA分别是u,v,其中u的深度大于等于v的深度,则交点一定包含u。
- 所以我们按照LCA的深度对读入的路径进行排序,然后按照深度从大到小进行遍历,如果发现当前路径的两端点属于之前已经标记过的子树,则此路径不需要选点,否则选择本条路径两端点的LCA,同时将该点所代表的子树进行标记,可以使用树链剖分和树状数组来完成这一任务。
AC代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(x) (x&(-x))
using namespace std;
const int N = 10000;
int n;
int fir[N + 5], nex[N * 2 + 5], vv[N * 2 + 5], co = 0;
void adde(int u, int v)
{
vv[++co] = v;
nex[co] = fir[u];
fir[u] = co;
}
int fa[N + 5];
int sq[N + 5], rk[N + 5], dep[N + 5];
int st[N + 5], sz[N + 5], chi[N + 5];
int cc[N + 5];
void update(int x, int v)
{
while (x <= n + 1)
{
cc[x] += v;
x += lowbit(x);
}
}
int qu(int x)
{
int res = 0;
while (x)
{
res += cc[x];
x -= lowbit(x);
}
return res;
}
struct ab
{
int f;
int u;
int v;
bool operator < (const ab& c) const
{
return dep[f] > dep[c.f];
}
} qq[N * 5 + 5];
void dfs1(int o, int f)
{
fa[o] = f;
dep[o] = dep[f] + 1;
sz[o] = 1;
chi[o] = 0;
for (int i = fir[o]; i; i = nex[i])
{
if (vv[i] == f)
{
continue;
}
dfs1(vv[i], o);
sz[o] += sz[vv[i]];
if (sz[vv[i]] > sz[chi[o]])
{
chi[o] = vv[i];
}
}
}
void dfs2(int o, int f, int top)
{
sq[++co] = o;
rk[o] = co;
st[o] = top;
if (chi[o])
{
dfs2(chi[o], o, top);
}
for (int i = fir[o]; i; i = nex[i])
{
if (vv[i] == f || vv[i] == chi[o])
{
continue;
}
dfs2(vv[i], o, vv[i]);
}
}
int lca(int u, int v)
{
while (st[u] != st[v])
{
if (dep[st[u]] < dep[st[v]])
{
swap(u, v);
}
u = fa[st[u]];
}
return dep[u] < dep[v] ? u : v;
}
int main()
{
while (scanf("%d", &n) == 1)
{
memset(fir, 0, sizeof(int) * (n + 2));
memset(cc, 0, sizeof(int) * (n + 2));
co = 0;
for (int i = 1; i <= n; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
++u;
++v;
adde(u, v);
adde(v, u);
}
co = 0;
dfs1(1, 0);
dfs2(1, 0, 1);
int q;
scanf("%d", &q);
for (int i = 1; i <= q; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
++u;
++v;
qq[i] = {lca(u, v), u, v};
}
sort(qq + 1, qq + q + 1);
int ans = 0;
for (int i = 1; i <= q; ++i)
{
if (qu(rk[qq[i].u]) || qu(rk[qq[i].v]))
{
continue;
}
++ans;
update(rk[qq[i].f], 1);
update(rk[qq[i].f] + sz[qq[i].f], -1);
}
printf("%d\n", ans);
}
return 0;
}
HDU 6203 ping ping ping 最近公共祖先 树状数组的更多相关文章
- 51nod 1681 公共祖先 | 树状数组
51nod 1681 公共祖先 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完 ...
- hdu 1556:Color the ball(第二类树状数组 —— 区间更新,点求和)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 3887:Counting Offspring(DFS序+树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...
- HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数
xiaoxin and his watermelon candy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5654 Description Du ...
- HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca
Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...
- HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Tota ...
- HDU 2227 Find the nondecreasing subsequences dp思想 + 树状数组
http://acm.hdu.edu.cn/showproblem.php?pid=2227 用dp[i]表示以第i个数为结尾的nondecreasing串有多少个. 那么对于每个a[i] 要去找 & ...
- POJ 3321:Apple Tree + HDU 3887:Counting Offspring(DFS序+树状数组)
http://poj.org/problem?id=3321 http://acm.hdu.edu.cn/showproblem.php?pid=3887 POJ 3321: 题意:给出一棵根节点为1 ...
- hdu 4715 Difference Between Primes(素数筛选+树状数组哈希剪枝)
http://acm.hdu.edu.cn/showproblem.php?pid=4715 [code]: #include <iostream> #include <cstdio ...
- HDU 4605 Magic Ball Game (dfs+离线树状数组)
题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值w. 接着给你一个权值为x的球,它从更节点开始向下掉,有三种情况 x=w[now]:停在此点 x<w[now]:当有孩子 ...
随机推荐
- Go语言常用标准库——context
文章目录 为什么需要Context 基本示例 全局变量方式 通道方式 官方版的方案 Context初识 Context接口 Background()和TODO() With系列函数 WithCance ...
- 使用ensp搭建路由拓扑,并使用ospf协议实现网络互通实操
转载请注明出处: 1.使用ENSP 搭建如下拓扑: 数据准备 为完成此配置例,需准备如下的数据: 设备 Router ID Process ID IP地址 DeviceA 1.1.1.1 1 区域0: ...
- 流水线中便捷迭代,鲲鹏DevKit 23.0新能力抢先看
本文分享自华为云社区<鲲鹏DevKit 23.0:流水线中便捷迭代鲲鹏版本,迁移.开发.调优无缝衔接>,作者:华为云社区精选 . 数字时代,海量的行业应用驱动着多样性算力的飞速发展,以鲲鹏 ...
- 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(9) -- 实现系统动态菜单的配置和权限分配
在WPF应用端开发,它的界面类似于Winform端,因此我们也需要对系统的菜单进行动态配置,这样才能把系统的功能弹性发挥到极致,通过动态菜单的配置方式,我们可以很容易的为系统新增所需的功能,通过权限分 ...
- [ABC207E] Mod i 题解
Mod i 题目大意 给定一个序列 \(a\),问将其划分成若干段,满足第 \(i\) 段的和是 \(i\) 的倍数的划分方案的个数. 思路分析 考虑 DP,设 \(f_{i,j}\) 表示将序列中前 ...
- 产品代码都给你看了,可别再说不会DDD(九):领域事件
这是一个讲解DDD落地的文章系列,作者是<实现领域驱动设计>的译者滕云.本文章系列以一个真实的并已成功上线的软件项目--码如云(https://www.mryqr.com)为例,系统性地讲 ...
- 一分钟理解TCP重传
为什么需要重传 任何信息在介质中传输可能丢失,这是由于传输介质的物理特性决定的,所以网络不可能被设计为"可靠的"(不是由于考虑"性能"原因而是压根做不到).既然 ...
- DDD技术方案落地实践
1. 引言 从接触领域驱动设计的初学阶段,到实现一个旧系统改造到DDD模型,再到按DDD规范落地的3个的项目.对于领域驱动模型设计研发,从开始的各种疑惑到吸收各种先进的理念,目前在技术实施这一块已经基 ...
- Linux MIPI 摄像头驱动框架编写(RN6752解码芯片)
一.概述 在编写 MIPI 摄像头驱动之前,需要先了解 Media 子系统的链路关系,这里我就不介绍了,需要的看我之前的笔记:Linux Media 子系统链路分析. 理解 Media 子系统链路关系 ...
- 手撕Vuex-安装模块数据
前言 根据上一篇,[手写Vuex]-提取模块信息,我们已经可以获取到模块的信息了,将模块信息变成了我们想要的数据结构,接下来我们就要根据模块的信息,来安装模块的数据. 在上一篇当中我们定义了一个 Mo ...