BZOJ 3910 火车 倍增LCA
本题并不需要并查集,每次查询一次最近公共祖先,并倍增求出需要被新标记的路径。
这样保证时间复杂度是 O(nlogn)O(nlogn)O(nlogn) 的。
Code:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 500000 + 4;
const int logn = 21;
int f[25][maxn], head[maxn], to[maxn << 1], nex[maxn << 1], cnt, n, m, s, dep[maxn];
bool tag[maxn];
long long ans;
inline void add_edge(int u,int v){
nex[++cnt] = head[u];
head[u] = cnt;
to[cnt] = v;
}
void dfs(int u,int fa, int depth)
{
f[0][u] = fa, dep[u] = depth;
for(int v = head[u]; v ; v = nex[v]){
if(to[v] != fa){
dfs(to[v], u, depth + 1);
}
}
}
inline int lca(int a,int b){ //b向 a 爬
if(dep[a] > dep[b]) swap(a,b);
if(dep[a] != dep[b]){
for(int i = logn;i >= 0; --i)
if(dep[f[i][b]] >= dep[a]) b = f[i][b];
}
if(a == b) return a;
for(int i = logn;i >= 0; --i)
{
if(f[i][a] != f[i][b])
{
a = f[i][a], b = f[i][b];
}
}
return f[0][a];
}
inline void connect(int a, int b){
if(tag[a] && tag[b]) return ;
if(dep[a] < dep[b]) swap(a, b); //a 爬向 b
int A = a;
if(tag[A])
{
for(int i = logn;i >= 0;--i)
if(tag[f[i][a]] == 1 ) a = f[i][a];
}
do
{
tag[a] = tag[f[0][a]] = 1;
a = f[0][a];
}while(a != b);
}
int main(){
scanf("%d%d%d",&n,&m,&s);
for(int i = 1;i < n ; ++i){
int a,b;
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a);
}
dfs(1, 0, 1);
for(int i = 1;i <= logn; ++i)
for(int j = 1;j <= n; ++j)
f[i][j] = f[i - 1][f[i - 1][j]];
int pre = s;
for(int i = 1;i <= m; ++i){
int cur;
scanf("%d",&cur);
int h = lca(pre, cur);
if(tag[cur] && tag[pre]) continue;
ans +=(long long) dep[cur] + dep[pre] - 2 * dep[h];
connect(pre, h);
connect(cur, h);
pre = cur;
}
printf("%lld",ans);
return 0;
}
BZOJ 3910 火车 倍增LCA的更多相关文章
- 【BZOJ-3910】火车 倍增LCA + 并查集
3910: 火车 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 262 Solved: 90[Submit][Status][Discuss] De ...
- BZOJ 3910: 火车
3910: 火车 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 358 Solved: 130[Submit][Status][Discuss] D ...
- BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- BFS+最小生成树+倍增+LCA【bzoj】4242 水壶
[bzoj4242 水壶] Description JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有 ...
- BZOJ 3732 Network —— 最小生成树 + 倍增LCA
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 <= N <= 15, ...
- BZOJ 3732 Network Kruskal+倍增LCA
题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 NOIP2013 货车运输.差点儿就是原题...仅仅只是最小边最大改成了最大边最小.. . 首先看到最大值最小第一 ...
- [板子]倍增LCA
倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...
- 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- Gym100685G Gadget Hackwrench(倍增LCA)
题目大概说一棵边有方向的树,q个询问,每次询问结点u是否能走到v. 倍增LCA搞即可: 除了par[k][u]表示u结点往上走2k步到达的结点, 再加上upp[k][u]表示u结点往上走2k步经过边的 ...
随机推荐
- 手动实现aop编程
手动实现aop编程(运用代理模式实现) aop:aspect object programming 功能:让关注点与业务代码分离 关注点:重复代码就叫做关注点 切面:关注点形成的类,就叫切面(类) 面 ...
- Express 初步使用
Express express 是 node 中最流行的框架之一. 1. 起步 安装: npm install express --save hello world const express = r ...
- php 常用header
//定义编码 header( 'Content-Type:text/html;charset=utf-8 '); //Atom header('Content-type: application/at ...
- 训练1-R
给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和. 例如,1 3 7 9 -1,查询第2个元素开始长度为3的子段和,1 {3 7 9} -1.3 + 7 + 9 = ...
- 基于 SpringMVC——web.xml基本配置
<!--声明应用范围内的初始化参数--> <context-param> <param-name>contextConfigLocation</param-n ...
- keepalived安装实现nginx主备高可用
. keepalived安装环境 su - root yum -y install kernel-devel* yum -y install openssl-* yum -y install popt ...
- E - QS Network
E - QS Network 思路:最小生成树,数组不要开小了. #include<cstdio> #include<cstring> #include<iostream ...
- redis代码解析-事务
redis 的事务相关的几个命令分别为 watch multi exec. watch 可以监控一个变量在事务开始执行之前是否有被修改.使用方式为: WATCH key [key ...] 在redi ...
- osEye.Net:离别是为了将来的重逢
这一时刻已经成为osEye历史..... 在热心网友的关怀和鼓励之下,osEye.net将继续运行着,感谢你们陪伴osEye一起走过.... 与你相知相恋已经有4个年头了,你的成长到成熟都让我历历在目 ...
- 回车登录(支持IE 和 火狐等浏览器)
$("body").keydown(function(e){ var curKey = e.which; if(curKey == 13){ $("#Btn_login& ...