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]:当有孩子 ...
随机推荐
- 其它——ZeroRPC和SimpleXMLRPCServer
文章目录 一 Python中RPC框架 二 SimpleXMLRPCServer使用 服务端 客户端 三 ZeroRPC使用 服务端 客户端 一 Python中RPC框架 自带的:SimpleXMLR ...
- 文心一言 VS 讯飞星火 VS chatgpt (113)-- 算法导论10.2 5题
五.用go语言,使用单向循环链表实现字典操作 INSERT.DELETE 和 SEARCH,并给出所写过程的运行时间. 文心一言: 在Go语言中,我们首先需要定义一个Node结构体来表示单向循环链表的 ...
- ida反汇编失败
options->general->打开堆栈指针(stack pointer) 可见反汇编失败提示的地址(本程序为00101481,原本此处不为000)处堆栈指针不为0,因此需要修改 al ...
- 如何在云服务上快速拥有洛甲WAF(Web防火墙)
如何在云服务上快速拥有洛甲WAF(Web防火墙) 洛甲WAF是基于openresty的web防火墙,通过配合后台保护您的数据安全,详情参考节点服务器 luojiawaf_lua(nginx+lua) ...
- 差异行压缩算法(C#实现)
private byte[] DifferenceRowOrder(int offset, int count, byte[] inbyte)//差异行命令(此处的offset和count都从1开始) ...
- C#/.NET/.NET Core优秀项目和框架2023年10月简报
前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(公众号每周至少推荐两个优秀的项目和框架当然节假日除外),公众号推文有项目和框架的介绍.功能特点以及部分截图等(打不开或 ...
- 数论笔记(Full Version)
数论笔记(Full Version) 一.数论基础: 1.整除: 重新定义除法: 对于计算式:\(a\div b\) 来说,其结果可以变化为以下的式子:$$a = b\lfloor \frac{a}{ ...
- 接雨水(4.4 leetcode每日打卡)
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可 ...
- 使用 TortoiseGit 在两个项目之间共享代码(cherry-pick)
需求:项目 A 需要新增项目 B 的部分代码,要求不变更 commit message 信息 做法 项目 A 新增上游 Remote,Remote URL 为 项目 B 的 URL 新增方式:依次点击 ...
- 数据库系列:RR和RC下,快照读的区别
数据库系列:MySQL慢查询分析和性能优化 数据库系列:MySQL索引优化总结(综合版) 数据库系列:高并发下的数据字段变更 数据库系列:覆盖索引和规避回表 数据库系列:数据库高可用及无损扩容 数据库 ...