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]:当有孩子 ...
随机推荐
- 一款Redis可视化工具:ARDM | 京东云技术团队
出众的软件有很多,适合自己的才是最好的. Another Redis Desktop Manager 更快.更好.更稳定的Redis桌面(GUI)管理客户端,兼容Windows.Mac.Linux,性 ...
- MySQL快速导入千万条数据(2)
目录 一.导入前1000万条数据 二.导入前2000万条数据 三.导入后面的1000万条数据 四.建索引 五.总结 接上文,继续测试3000万条记录快速导入数据库. 一.导入前1000万条数据 清库. ...
- 一次考试的简单T3
我的第一个想法其实是毫无头绪 根本就想不到dp,直接就写了爆搜后来讲了才知道... 这种dp的状态好像是一类dp的模型,他们的状态都有这样的一维:以第i个数结尾.这样的dp有什么样的标志呢?以第i个数 ...
- JDK21的虚拟线程是什么?和平台线程什么关系?
虚拟线程(Virtual Thread)是 JDK 而不是 OS 实现的轻量级线程(Lightweight Process,LWP),由 JVM 调度.许多虚拟线程共享同一个操作系统线程,虚拟线程的数 ...
- z函数|exkmp|拓展kmp 笔记+图解
题外话,我找个什么时间把kmp也加一下图解 z函数|exkmp 别担心 这个exkmp和kmp没毛点关系,请放心食用. 本文下标以1开始,为什么?因为1开始就不需要进行长度和下标的转换,长度即下标. ...
- 文心一言 VS 讯飞星火 VS chatgpt (123)-- 算法导论10.4 4题
四.用go语言,对于一个含 n个结点的任意有根树,写出一个 O(n)时间的过程,输出其所有关键字该树以左孩子右兄弟表示法存储. 文心一言: 在计算机科学中,左孩子右兄弟表示法是一种用于表示树状结构的方 ...
- Idea单窗口导入多个项目模块
现在我们比较流行微服务,但是服务一旦多了,项目打开也是很麻烦的,运行内存16个G的电脑,基本上打开4,5个项目模块就顶不住了.那么,我们怎么把多个项目导入到一个idea窗口中呢? 实现效果 导入步骤 ...
- 通过mybatis-plus的自定义拦截器实现控制 mybatis-plus的全局逻辑删除字段的控制 (修改其最终执行的sql中的where条件)
需求:过滤部分请求不实现mybatis-plus的逻辑删除 看到网上关于mybatis-plus的自定义拦截器的文章有的少 想了想自己写了一篇 欢迎参考 指正 通过springboot的拦截器 在请求 ...
- pbootcms 后台内容列表搜索功能扩展及增加显示字段功能
应项目要求,一个内容模型下栏目不宜分的层级过多,如新闻模块,分2022.2023.2024年度,每年度下分12个月,这样就是2层栏目,再依类别(科技.动漫.电影...)划分层级,栏目数量较多,而且不易 ...
- Android Recyclerview的item间距实现
Recyclerview中,提供了一个方法addItemDecoration给我们用于设置item的分割线 下面提供几个常见的分割线效果 注: 下面的SizeUtils是AndroidUtilCode ...