cf592d
题意:给出一个无根树,点数为10^5,所有边的长度为1。给定其中有一些点是受到攻击的。
现在要求一个人选定一个点作为起点,走遍所有的受攻击点(不用再回到起点)。
需要的最短距离是多少,选定的起点是哪个。
分析:这是一个求树直径的变形题,原版请看这里。
求树的直径即树中最远的点对,需要进行两次bfs或者dfs。这里我们用的是dfs。
首先我们假设所有点都受到攻击,那么要走完所有点再回到起点,路程L就是树上所有边的长度和乘以2。
不用回到起点遍历所有点的最短距离就是用这个L减去树上的最远两点之间的距离。
我们要把起点选在最远点对中的点才能保证所得解最小。
但本题中不是所有点都受到攻击,所以在求最远点对的时候要进行一些改变。要找最远的受攻击点对。
首先要以一个受攻击点为根(这个是本题最大难点,不太容易想到),进行第一次dfs,找到最深的受攻击点之后,再以它为根找最深的受攻击点。(注意长度相同时,找编号最小的)
再求出以任意受攻击点为根,遍历所有受攻击点的路程和。两者相减即为解。
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std; const int MAX_N = (int)(2e5) + ; int n, m;
int root;
vector<int> g[MAX_N];
bool attacked[MAX_N];
int depth[MAX_N];
long long path_len; void input()
{
scanf("%d%d", &n, &m);
for (int i = ; i < n - ; i++)
{
int a, b;
scanf("%d%d", &a, &b);
a--;
b--;
g[a].push_back(b);
g[b].push_back(a);
}
memset(attacked, , sizeof(attacked));
for (int i = ; i < m; i++)
{
int a;
scanf("%d", &a);
a--;
attacked[a] = true;
}
} void dfs(int u, int father)
{
for (int i = ; i < (int)g[u].size(); i++)
{
int v = g[u][i];
if (v == father)
continue;
depth[v] = depth[u] + ;
dfs(v, u);
}
} int find_next()
{
int ret = root;
for (int i = ; i < n; i++)
{
if (!attacked[i])
continue;
if (depth[i] > depth[ret] || (depth[i] == depth[ret] && i < ret))
{
ret = i;
}
}
return ret;
} bool cal_depth(int u, int father)
{
bool ret = false;
for (int i = ; i < (int)g[u].size(); i++)
{
int v = g[u][i];
if (v == father)
continue;
if (!cal_depth(v, u))
continue;
path_len += ;
ret = true;
}
return ret || attacked[u];
} int main()
{
input();
root = find(attacked, attacked + n, true) - attacked; depth[root] = ;
dfs(root, -);
root = find_next(); depth[root] = ;
dfs(root, -); int end = find_next();
int city = min(root, end);
path_len = ;
cal_depth(root, -);
printf("%d\n%I64d\n", city + , path_len - depth[end]);
return ;
}
cf592d的更多相关文章
- CF592D Super M
嘟嘟嘟 首先这题虽然不是很难,但是黄题是不是有点过分了--好歹算个蓝题啊. 手玩样例得知,这哥们儿瞬移到的城市\(A\)一定是这些被攻击的城市构成的树的一个叶子,然后他经过的最后一个城市\(B\)和\ ...
- 树的直径-CF592D Super M
给定一颗n个节点树,边权为1,树上有m个点被标记,问从树上一个点出发,经过所有被标记的点的最短路程(起终点自选).同时输出可能开始的编号最小的那个点.M<=N<=123456. 先想:如果 ...
随机推荐
- WinForm使用皮肤图文步骤
Winfrom本身样式提供的是Windows经典样式.. 不说多丑也绝称不上好看..有时为了用户体验就不得不需要想办法弄漂亮一点..皮肤包会是一个不错的选择.. 不废话了..开整.. 首先从网上下载免 ...
- ServletContext中常用方法
..获取Tomcat的Context的初始化参数. 1.获取Tomcat的server.xml中设置Context的初始化参数. 例如: <Context path="/testcon ...
- 正确地组织python项目的结构
统一的项目结构 写了不少python项目后, 越来越认识到python项目结构重要性. 不管项目是否要开源, 是否要提交pypi, 项目结构的一致性带来的好处还有很多: 多人合作开发大家都有个基本的g ...
- Java项目相关监控与调优
Linux JVM Tomcat =========Linux =============== 监控 nmon 命令:nmon -s 10 -c 60 -f -m /home -s 10 每10s ...
- Code First04---关于上下文DbContext
这章主要讲怎么配置DbContext的子类访问的数据库的位置. 我相信大家最经常使用的数据库位置的配置方式就是配置文件了,也就是通过App.Config 或Web.Config来配置要访问的数据库. ...
- 流媒体(音频 AudioStreamer)
AudioStreamer 在github可以搜索到, 专门播放流媒体(音频)
- DOM的相关优化
为什么要进行DOM优化? DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢,而是说操作了这个对象后,会触发一些浏览器行为,比如布局(layout)和绘制(paint). 首先先说一些 ...
- 使用 Intel HAXM 为 Android 模拟器加速,媲美真机
http://www.cnblogs.com/beginor/archive/2013/01/13/2858228.html
- HTML 5 <input> placeholder 属性
原文链接:http://www.w3school.com.cn/html5/att_input_placeholder.asp HTML 5 <input> placeholder 属性 ...
- Sqli-LABS通关笔录-16
这个关卡之前我还使用了一下工具跑,发现居然跑不出来.这就尴尬了.行吧手工试试. payload admin") and If(ascii(substr(database(),1,1))=11 ...