不能走路(walk)
【题目背景】
小G 同学总是在树上走路。小S 看不下去了,决定阻止小G 同学。
【题目描述】
有一棵 n 个点的树,树上有 m 条路径,每条路径为 x[i]到y[i] 的树上最短路径(不经过相同的边),小 S 想要摧毁树上的 K 个点, 使得每一条路径上都有至少一个点被摧毁。
你只需要求出最小的K,而不用输出摧毁了哪些点。
| 数据点编号 | n<= | m<= |
|---|---|---|
| 1 | 15 | 15 |
| 2 | 100 | 15 |
| 3 | 100 | 15 |
| 4 | 100 | 100 |
| 5 | 1000 | 1000 |
| 6 | 5000 | 5000 |
| 7 | 5000 | 5000 |
| 8 | 100000 | 100000 |
| 9 | 100000 | 100000 |
| 10 | 100000 | 100000 |
【样例输入】
5 2
1 2
2 3
2 4
2 5
1 5
3 4
【样例输出】
1
【提示】
如果需要用到较大的栈空间。
可以在编译命令加上-Wl,--stack=2333333333。评测时开栈。
题解
受洛谷P1967 货车运输启发,这题很像LCA。
于是我们就尝试切LCA。
首先,不难发现阻断LCA是可行的,那么是最优的吗?
对于一颗子树内的点,如果从该子树的点要延伸出子树外,那必须经过最顶端的点。
如图,对于一个点,若要与外面有联系,那必定要经过\(lca(a,b)\)。
那两点的联系在子树内呢?如果是\(c\to d\),那显然是无关的,那\(e\to b\)呢?我们发现最优应该切\(lca(e, b)\)。

那不是就WA了吗?不。我们发现:如果我们先切\(lca(e, b)\),到\(a\to b\)是特判一下即可。
由于数据很水,判是否联通用暴力爬就可以了。
下面上代码,刚学树剖,于是就打了个树剖。
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100005;
struct Edge
{
int to, nxt;
} e[maxn<<1];
int first[maxn];
int nowm;
inline void add_edge(int from, int to)
{
e[++nowm].nxt = first[from];
e[nowm].to = to;
first[from] = nowm;
e[++nowm].nxt = first[to];
e[nowm].to = from;
first[to] = nowm;
}
int fa[maxn], son[maxn], dep[maxn], val[maxn];
inline void dfs1(int x)//找重链,标记深度与父亲
{
dep[x] = dep[fa[x]] + 1;
val[x] = 1;
for(int i = first[x], dd; i; i = e[i].nxt)
{
dd = e[i].to;
if(dd == fa[x])
continue;
fa[dd] = x;
dfs1(dd);
val[x] += val[dd];
if(!son[x] || val[dd] > val[son[x]])
son[x] = dd;
}
}
int top[maxn];
inline void dfs2(int x, int ff)//寻找重链的顶端
{
top[x] = ff;
if(son[x])
dfs2(son[x], ff);
for(int i = first[x], dd; i; i = e[i].nxt)
{
dd = e[i].to;
if(dd != fa[x] && dd != son[x])
dfs2(dd, dd);
}
}
inline void init(int s)
{
dfs1(s);
dfs2(s, s);
}
inline int lca(int a, int b)
{
while(top[a] != top[b])
{
if(dep[top[a]] >= dep[top[b]])
a = fa[top[a]];
else
b = fa[top[b]];
}
return dep[a] < dep[b] ? a : b;
}
struct sxd
{
int a, b, t;
inline bool operator < (const sxd& other) const
{
return dep[t] > dep[other.t];
}
} ask[maxn];
bool biao[maxn];
inline bool pan(int a, int b)
{
for(; a != fa[b]; a = fa[a])
if(biao[a])
return true;
return false;
}
int main()
{
freopen("walk.in", "r", stdin);
freopen("walk.out", "w", stdout);
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1, f, t; i < n; ++i)
{
scanf("%d%d", &f, &t);
add_edge(f, t);
}
init(1);
for(int i = 1; i <= m; ++i)
{
scanf("%d%d", &ask[i].a, &ask[i].b);
ask[i].t = lca(ask[i].a, ask[i].b);//树剖lca模板
}
sort(ask+1, ask+m+1);//将提问排序,从下往上阻断
int ans = 0;
for(int i = 1; i <= m; ++i)//暴力往上爬……(竟不会T,还是最优解)
{
if(pan(ask[i].a, ask[i].t) || pan(ask[i].b, ask[i].t))
continue;
ans++;
biao[ask[i].t] = true;
}
printf("%d\n", ans);
return 0;
}
不能走路(walk)的更多相关文章
- 学C#之设计模式系列笔记(1)策略模式
一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,策略模式,https://zh.wikipedia.or ...
- Quick StateMachine状态机
状态机quick中是一个亮点,假设我们做一款RPG游戏,一个角色通常会拥有idle,attack,walk.run,death这些状态,假设游戏角色的状态採用分支条件推断的话.会造成很庞大而难以维护. ...
- Openjudge-计算概论(A)-骑车与走路
描述: 在北大校园里,没有自行车,上课办事会很不方便.但实际上,并非去办任何事情都是骑车快,因为骑车总要找车.开锁.停车.锁车等,这要耽误一些时间.假设找到自行车,开锁并车上自行车的时间为27秒;停车 ...
- hdu_A Walk Through the Forest ——迪杰特斯拉+dfs
A Walk Through the Forest Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/ ...
- 计算概论(A)/基础编程练习2(8题)/4:骑车与走路
#include<stdio.h> int main() { // 待处理的数据数量n ; scanf("%d", &n); float meters[n]; ...
- Spoken English Practice(And I can't walk. Should i just stay home and pout about it?)
绿色:连读: 红色:略读: 蓝色:浊化: 橙色:弱读 下划线_为浊化 口语蜕变(2017/7/12) ...
- 【ACM】bailian_2703_骑车与走路_201307301543
2703:骑车与走路总时间限制: 1000ms 内存限制: 65536kB 描述 在北大校园里,没有自行车,上课办事会很不方便.但实际上,并非去办任何事情都是骑车快,因为骑车总要找车.开锁.停车.锁车 ...
- OpenJudge计算概论-骑车与走路
/*============================================================ 骑车与走路 总时间限制: 1000ms 内存限制: 65536kB 描述 ...
- python os.walk()
os.walk()返回三个参数:os.walk(dirpath,dirnames,filenames) for dirpath,dirnames,filenames in os.walk(): 返回d ...
随机推荐
- .NET 微服务 学习目录
概述 微服务在Java端已经有很成熟的框架可以使用,之前.NET一直没有比较成熟的网关,最近发现 Ocelot 这个.NET开源的微服务网关功能越来越强大,正好照着微软的官方文档学些一下.NET的微服 ...
- CentOS7安装RabbitMQ,并设置远程访问
如果网速慢 可以直接到百度云分享中下载,然后拉到centerOS中,进行第二步即可 两个人安装包地址,提取码:z1oz 1.安装erlang环境 wget http://www.rabbit ...
- [转帖]UML类图关系图解
UML类图关系图解 https://www.cnblogs.com/TvvT-kevin/p/9357339.html 一.类结构 在类的UML图中,使用长方形描述一个类的主要构成,长方形垂直地分为三 ...
- Android.mk文件官方使用说明
本页介绍了 ndk-build 所使用的 Android.mk 编译文件的语法. 概览 Android.mk 文件位于项目 jni/ 目录的子目录中,用于向编译系统描述源文件和共享库.它实际上是编译系 ...
- 启动Sonar报错,ERROR: [1] bootstrap checks failed [1]: system call filters failed to install
错误提示信息: ERROR: [1] bootstrap checks failed[1]: system call filters failed to install; check the logs ...
- Java学习:面向对象的三大特征:封装性、继承性、多态性之继承性
面向对象的三大特征:封装性.继承性.多态性. 继承 继承是多态的前提 ,如果没有继承,就没有多态. 继承主要解决的问题就是:共性抽取. 继承关系当中的特点: 子类可以拥有父类的“内容” 子类还可以拥有 ...
- JDK9版本以上Java独有的一个轻量级小工具,你知道吗?jshell
jshell,是JavaJDK9这个大版本更新以来,带来的一个轻量级小工具.我们再也不用进入Java目录,编写一个Java文件,然后再去编译,最后才能执行它. 这里,你可以直接写一个小功能,就能去实现 ...
- 开发dubbo应用程序(二)dubbo注册中心相关概述
1.注册中心概述 在Dubbo微服务体系中,注册中心是其核心组件之一.Dubbo通过注册中心实现了分布式环境中各微服务之间的注册与发现,是各分布式节点之间的纽带.其主要作用如下: 动态加入.一个服 ...
- 订单BOM与销售BOM的区别
訂單BOM: 是實際生產時用的BOM, 在標準BOM和銷售BOM基礎上增減物料的BOM 銷售BOM: 是為特定客戶設定的BOM, 在主檔數據層次上的BOM, 在生產時是帶到訂單BOM中去的. 標準BO ...
- 在配置和销售凭证 GET_CONFIG_MODE 间通信时内部出错
“在配置和销售凭证 GET_CONFIG_MODE 间通信时内部出错” 订单打开出现这种错误提示,多半是配置对象号问题. SAP NOTE 2019-09-27 901893901893 - Repo ...