【题目背景】

小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)的更多相关文章

  1. 学C#之设计模式系列笔记(1)策略模式

    一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,策略模式,https://zh.wikipedia.or ...

  2. Quick StateMachine状态机

    状态机quick中是一个亮点,假设我们做一款RPG游戏,一个角色通常会拥有idle,attack,walk.run,death这些状态,假设游戏角色的状态採用分支条件推断的话.会造成很庞大而难以维护. ...

  3. Openjudge-计算概论(A)-骑车与走路

    描述: 在北大校园里,没有自行车,上课办事会很不方便.但实际上,并非去办任何事情都是骑车快,因为骑车总要找车.开锁.停车.锁车等,这要耽误一些时间.假设找到自行车,开锁并车上自行车的时间为27秒;停车 ...

  4. hdu_A Walk Through the Forest ——迪杰特斯拉+dfs

    A Walk Through the Forest Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/ ...

  5. 计算概论(A)/基础编程练习2(8题)/4:骑车与走路

    #include<stdio.h> int main() { // 待处理的数据数量n ; scanf("%d", &n); float meters[n]; ...

  6. Spoken English Practice(And I can't walk. Should i just stay home and pout about it?)

    绿色:连读:                  红色:略读:               蓝色:浊化:               橙色:弱读     下划线_为浊化 口语蜕变(2017/7/12) ...

  7. 【ACM】bailian_2703_骑车与走路_201307301543

    2703:骑车与走路总时间限制: 1000ms 内存限制: 65536kB 描述 在北大校园里,没有自行车,上课办事会很不方便.但实际上,并非去办任何事情都是骑车快,因为骑车总要找车.开锁.停车.锁车 ...

  8. OpenJudge计算概论-骑车与走路

    /*============================================================ 骑车与走路 总时间限制: 1000ms 内存限制: 65536kB 描述 ...

  9. python os.walk()

    os.walk()返回三个参数:os.walk(dirpath,dirnames,filenames) for dirpath,dirnames,filenames in os.walk(): 返回d ...

随机推荐

  1. 解决myeclipse2017 properties中文被Unicode编码

    输入:http://propedit.sourceforge.jp/eclipse/updates/ 在线安装插件解决.

  2. cad.net 获取所有已经安装的cad版本信息

    计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\Hardcopy var ackey = Registry.LocalMachine.OpenSubKey(@&quo ...

  3. 【RS】:论文《Neural Collaborative Filtering》的思路及模型框架

    [论文的思路] NCF 框架如上: 1.输入层:首先将输入的user.item表示为二值化的稀疏向量(用one-hot encoding) 2.嵌入层(embedding):将稀疏表示映射为稠密向量( ...

  4. centos上nginx转发tcp请求

    下载最新版nginx > wget http://nginx.org/download/nginx-1.17.1.tar.gz 解压缩 > tar zxvf nginx-1.17.1.ta ...

  5. NanoPi NEO Plus2开发环境搭建

    1.前言 NanoPi NEO Plus2是友善电子推出的一款非常小巧精致的开源硬件,该开源硬件的CPU是基于Allwinner公司的64位四核ARM Cortex-A53处理器H5,并且内置了六核M ...

  6. python入门之模块

    序什么是包包的作用一.什么是模块二.模块的三种来源三.模块的四种表现形式四.为什么要使用模块五. 如何创建,编写模块,并使用模块5.1 给模块起别名5.2 模块的导入方式5.3 循环导入问题 TOC ...

  7. 025 Linux基础入门-----历史、简介、版本、安装

    1.linux历史 Linux最初是由芬兰赫尔辛基大学学生Linus Torvalds由于自己不满意教学中使用的MINIX操作系统, 所以在1990年底由于个人爱好设计出了LINUX系统核心.后来发布 ...

  8. 国产服务器创建GSCloud实例统计

    1. GSCloud 201909 版本 完整的数据库实例 龙芯上面的瀚高4.3.4.3 数据库实例 安装耗时: 服务器配置: 龙芯3A 四核 .45G 内存8G HDD硬盘 安装耗时: 52min ...

  9. pycharm社区办找不到View-->Tool Windows->DataBase的解决办法

    File->Settings->Plugins->Database Navigator 安装

  10. day59——orm单表操作

    day59 orm单表操作 对象关系映射(object relational mapping) orm语句 -- sql -- 调用pymysql客户端发送sql -- mysql服务端接收到指令并执 ...