原题链接

题意

  • 给我们一棵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 最近公共祖先 树状数组的更多相关文章

  1. 51nod 1681 公共祖先 | 树状数组

    51nod 1681 公共祖先 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完 ...

  2. hdu 1556:Color the ball(第二类树状数组 —— 区间更新,点求和)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

  4. HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数

    xiaoxin and his watermelon candy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5654 Description Du ...

  5. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

  6. HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Tota ...

  7. HDU 2227 Find the nondecreasing subsequences dp思想 + 树状数组

    http://acm.hdu.edu.cn/showproblem.php?pid=2227 用dp[i]表示以第i个数为结尾的nondecreasing串有多少个. 那么对于每个a[i] 要去找 & ...

  8. 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 ...

  9. hdu 4715 Difference Between Primes(素数筛选+树状数组哈希剪枝)

    http://acm.hdu.edu.cn/showproblem.php?pid=4715 [code]: #include <iostream> #include <cstdio ...

  10. HDU 4605 Magic Ball Game (dfs+离线树状数组)

    题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值w. 接着给你一个权值为x的球,它从更节点开始向下掉,有三种情况 x=w[now]:停在此点 x<w[now]:当有孩子 ...

随机推荐

  1. 爬虫系列——Beautifulsoup4

    文章目录 一 介绍 二 基本使用 三 遍历文档树 四 搜索文档树 五 修改文档树 六 总结 ​ 一 介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能 ...

  2. 前端三件套系例之CSS——响应式布局

    文章目录 1.什么是响应式设计 1-1 定义 1-2 响应式设计的优势 2.屏幕的相关概念 3.viewport 视口 3-1 什么是viewport 3-2 设置viewport 4.媒体查询 @m ...

  3. 2023 版 Java和python开发线性代数探索

    目录 前景提示 需求 分析 1.初始化不需要指定矩阵的尺寸,并且可以直接传入数据. 2.可以计算2x2矩阵的逆 3.可以做2x2的矩阵乘法 Java版本开发 一. 开发详情 1.开发一个子类,如图所示 ...

  4. Go语言代码断行规则详解

    本文深入探讨了Go语言中代码断行的各个方面,从基础概念到实际应用实践. 关注[TechLeadCloud],分享互联网架构.云服务技术的全维度知识.作者拥有10+年互联网服务架构.AI产品研发经验.团 ...

  5. 【Azure Logic App】在Azure Logic App中使用SMTP发送邮件示例

    问题描述 在Azure Logic App的官网介绍中,使用SMTP组件发送邮件非常简单(https://docs.azure.cn/zh-cn/connectors/connectors-creat ...

  6. Godot引擎的一些踩坑记录(不断更新中)

    版本号 Godot 3.1.2 文件夹名称使用小写.编译\导出时有的tscn文件的引用路径, 有可能会变成小写路径(怀疑是bug),导致启动失败. ttc字体(文泉驿微米黑)导出时需要手动设置包含*. ...

  7. JavaScript高级程序设计笔记04 变量、作用域与内存

    变量.作用域与内存 变量 特定时间点一个特定值的名称. 分类 原始值:按值访问 复制:两个独立使用.互不干扰 引用值(由多个值构成的对象):按引用访问 操作对象时,实际上操作的是对该对象的引用(ref ...

  8. 小满OKKICRM与金蝶云星空对接集成客户资料

    小满OKKICRM与金蝶云星空对接集成客户列表查询(更新列表)&客户新增(小满客户对接金蝶客户-P) 数据源平台:小满OKKICRM 小满科技成立于2013年,是阿里巴巴集团战略投资的高新技术 ...

  9. HoG / SIFT 学习指北

    本文 OI / ACM 无关. Explain HoG 原文出处: N. Dalal, and B. Triggs, Histograms of oriented gradients for huma ...

  10. [JDK/APM] 应用诊断工具之VisualVM

    1 概述 1.1 简介 VisualVM is a visual tool integrating commandline JDK tools and lightweight profiling ca ...