嘟嘟嘟




首先这题虽然不是很难,但是黄题是不是有点过分了……好歹算个蓝题啊。




手玩样例得知,这哥们儿瞬移到的城市\(A\)一定是这些被攻击的城市构成的树的一个叶子,然后他经过的最后一个城市\(B\)和\(A\)构成的链一定是这棵新构成的树的直径(突然想到虚树)。

别激动,这题根本不用虚树。

我们只用求一遍树的直径就行了,只不过这个直径的端点必须满足都是被攻击的城市,则第一问就是端点中的较小值。




考虑第二问。

直径上的城市只会走一遍,而直径外的城市必须走过去再回来。所以我们从直径一段开始遍历整个直径,每经过一个点,就dfs这个点直径之外的子树,并统计子树内走到被攻击的城市的距离和。那么答案就是这些距离+加树的直径长度。

距离和的求法用树形dp就行。我们考虑每一条边的贡献。如果一个点的的儿子的子树内有被攻击的城市,则这条边一定会被走过,答案加2即可。




然后记得特判被攻击的城市只有一个的情况(被hack了……)。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 2e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int n, m;
bool vis[maxn];
struct Edge
{
int nxt, to;
}e[maxn << 1];
int head[maxn], ecnt = -1;
In void addEdge(int x, int y)
{
e[++ecnt] = (Edge){head[x], y};
head[x] = ecnt;
} int dep[maxn], fa[maxn], Max = 0, A, B;
In void dfs1(int now, int _f, int dis, int& id)
{
if(vis[now] && (dis > Max || (dis == Max && now < id))) Max = dis, id = now;
dep[now] = dep[_f] + 1; fa[now] = _f;
for(int i = head[now], v; ~i; i = e[i].nxt)
if((v = e[i].to) ^ _f) dfs1(v, now, dis + 1, id);
} bool dia[maxn];
int a[maxn], b[maxn], acnt = 0, bcnt = 0;
In void solve(int x, int y)
{
a[++acnt] = x; b[++bcnt] = y;
dia[x] = dia[y] = 1;
while(x ^ y)
{
if(dep[x] > dep[y]) a[++acnt] = x = fa[x], dia[x] = 1;
else b[++bcnt] = y = fa[y], dia[y] = 1; }
--acnt;
} int ans = 0;
In bool dfs2(int now, int _f, int dis)
{
int flg = 0;
for(int i = head[now], v; ~i; i = e[i].nxt)
{
if(dia[v = e[i].to] || v == _f) continue;
int tp = dfs2(v, now, dis + 1);
if(tp) ans += 2;
flg |= tp;
}
return flg || vis[now];
} int main()
{
Mem(head, -1);
n = read(), m = read();
for(int i = 1; i < n; ++i)
{
int x = read(), y = read();
addEdge(x, y), addEdge(y, x);
}
for(int i = 1; i <= m; ++i) A = read(), vis[A] = 1;
dfs1(A, 0, 0, A), Max = 0, dfs1(A, 0, 0, B);
if(!A || !B) {printf("%d\n0\n", A | B); return 0;}
solve(A, B);
for(int i = 1; i <= acnt; ++i) dfs2(a[i], 0, 0); //这两行是遍历直径
for(int i = 1; i <= bcnt; ++i) dfs2(b[i], 0, 0);
write(min(A, B)), enter, write(ans + Max), enter;
return 0;
}

CF592D Super M的更多相关文章

  1. 树的直径-CF592D Super M

    给定一颗n个节点树,边权为1,树上有m个点被标记,问从树上一个点出发,经过所有被标记的点的最短路程(起终点自选).同时输出可能开始的编号最小的那个点.M<=N<=123456. 先想:如果 ...

  2. 子类继承父类时JVM报出Error:Implicit super constructor People() is undefined for default constructor. Must define an explicit constructor

    当子类继承父类的时候,若父类没有定义带参的构造方法,则子类可以继承父类的默认构造方法 当父类中定义了带参的构造方法,子类必须显式的调用父类的构造方法 若此时,子类还想调用父类的默认构造方法,必须在父类 ...

  3. [LeetCode] Super Ugly Number 超级丑陋数

    Write a program to find the nth super ugly number. Super ugly numbers are positive numbers whose all ...

  4. Maven Super POM

    Maven super POM defines some properties. Three ways to find it ${M2_HOME}/lib/maven-model-builder-3. ...

  5. java基础 super 子类调用父类

    如果希望在子类中,去调用父类的构造方法,要求在子类的构造函数调用 example如下: package test; /* * 如果希望在子类中,去调用父类的构造方法,要求在子类的构造函数调用 * */ ...

  6. Python类中super()和__init__()的关系

    Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...

  7. java方法重载(overload)、重写(override);this、super关键简介

    一.方法重载: 条件:必须在一个类中,方法名称相同,参数列表不同(包括:数据类型.顺序.个数),典型案例构 造方重载.  注意:与返回值无关 二.方法重写: 条件: (1)继承某个类或实现某接口 (2 ...

  8. Java super关键字活用

    在实际开发中我们要自定义组件,就需要继承自某个组件类,如果我们自定义的这个组件类也需要像被继承的这个组件类一样,拥有丰富的构造方法. 关键字super的作用就更加显得尤为重要了,你可以在堆砌自己自定义 ...

  9. 深入super,看Python如何解决钻石继承难题 【转】

    原文地址 http://www.cnblogs.com/testview/p/4651198.html 1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...

随机推荐

  1. SSM-SpringMVC-23:SpringMVC中初探异常解析器

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客要讲的是异常解析器,SimpleMappingExceptionResolver简单映射异常解析器 可 ...

  2. 你必须知道的EntityFramework 6.x和EntityFramework Core变更追踪状态

    前言 只要有时间就会时不时去看最新EF Core的进展情况,同时也会去看下基础,把握好基础至关重要,本节我们对比看看如标题EF 6.x和EF Core的不同,希望对正在学习EF Core的同行能有所帮 ...

  3. U型理论

  4. CORS 实战 专题

    本文会代码层面对CORS问题进行剖析 CORS相关相关概念可参考http://www.cnblogs.com/softidea/p/5496719.html ERROR info: XMLHttpRe ...

  5. 使用Ratpack与Spring Boot构建高性能JVM微服务

    在微服务天堂中Ratpack和Spring Boot是天造地设的一对.它们都是以开发者为中心的运行于JVM之上的web框架,侧重于生产率.效率以及轻量级部署.他们在服务程序的开发中带来了各自的好处.R ...

  6. Tornado框架实现图形验证码功能

    图形验证码是项目开发过程中经常遇到的一个功能,在很多语言中都有对应的不同形式的图形验证码功能的封装,python 中同样也有类似的封装操作,通过绘制生成一个指定的图形数据,让前端HTML页面通过链接获 ...

  7. win10想开测试模式,提示“设置元素数据时出错

    系统中按WIN键,搜索栏输入'CMD',右键点击找到的cmd.exe,选择'以管理员身份运行'.输入:"bcdedit -set loadoptions DDISABLE_INTEGRITY ...

  8. [UOJ#207. 共价大爷游长沙]——LCT&随机化

    题目大意: 传送门 给一颗动态树,给出一些路径并动态修改,每次询问一条边是否被所有路径覆盖. 题解: 先%一发myy. 开始感觉不是很可做的样子,发现子树信息无论维护什么都不太对…… 然后打开题目标签 ...

  9. WinForm加载外部类库项目的集成开发模式

    在项目开发中有一定的团队用到了Nuget.Coding:但是这用起来还是不太方方便,在Winform中呢,我们可以把一个人的项目当作一个类库项目,因为它生成的是一个dll文件,也就是单一文件,拥有了它 ...

  10. Celery异步调度框架(二)与Django结合使用

    配置Celery与Django结合 需要安装的插件 # 用于在Django中执行任务 pip install django-celery-beat # 这个是把任务执行结果保存到django-orm中 ...