3910: 火车

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 358  Solved: 130
[Submit][Status][Discuss]

Description

A 国有n 个城市,城市之间有一些双向道路相连,并且城市两两之间有唯一
路径。现在有火车在城市 a,需要经过m 个城市。火车按照以下规则行驶:每次
行驶到还没有经过的城市中在 m 个城市中最靠前的。现在小 A 想知道火车经过
这m 个城市后所经过的道路数量。 

Input

第一行三个整数 n、m、a,表示城市数量、需要经过的城市数量,火车开始
时所在位置。 
接下来 n-1 行,每行两个整数 x和y,表示 x 和y之间有一条双向道路。 
接下来一行 m 个整数,表示需要经过的城市。 

Output

一行一个整数,表示火车经过的道路数量。 

Sample Input

5 4 2
1 2
2 3
3 4
4 5
4 3 1 5

Sample Output

9

HINT

N<=500000 ,M<=400000 

Source

分析:

在经历了无数次对题意的错误理解(和被YouSiki的无数次吐槽)之后,我理解对了题意,然后觉得可能是个暴力...

事实证明这就是个暴力,我们每一次暴力标记访问过的节点,然后并查集维护,如果访问过就把这个点并到父亲上,均摊复杂度显然是$O(N)$的...

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std; const int maxn=500000+5; int n,m,st,cnt,a[maxn],f[maxn],hd[maxn],to[maxn<<1],fa[maxn][25],dep[maxn],nxt[maxn<<1];
long long ans; inline int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
} inline void add(int x,int y){
to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++;
} inline void dfs(int x){
for(int i=hd[x];i!=-1;i=nxt[i])
if(to[i]!=fa[x][0])
fa[to[i]][0]=x,
dep[to[i]]=dep[x]+1,dfs(to[i]);
} inline void init(void){
for(int j=1;j<=20;j++)
for(int i=1;i<=n;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
} inline int LCA(int x,int y){
if(dep[x]<dep[y])
swap(x,y);
int d=dep[x]-dep[y];
for(int i=20;i>=0;i--)
if((d>>i)&1)
x=fa[x][i];
if(x==y)
return x;
for(int i=20;i>=0;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
} signed main(void){
memset(hd,-1,sizeof(hd));
scanf("%d%d%d",&n,&m,&st);
for(int i=1,x,y;i<n;i++)
scanf("%d%d",&x,&y),add(x,y),add(y,x);
dep[1]=1,fa[1][0]=1,dfs(1);init();
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
for(int i=1,x,y,lca;i<=m;i++){
if(find(a[i])!=a[i])
continue;
x=st,y=a[i],lca=LCA(x,y);
while(dep[x]>=dep[lca]){
if(find(x)==x)
f[x]=x==1?0:fa[x][0];
else
x=find(x);
}
while(dep[y]>=dep[lca]){
if(find(y)==y)
f[y]=y==1?0:fa[y][0];
else
y=find(y);
}
x=st,y=a[i],st=a[i];
ans+=dep[x]-dep[lca];
ans+=dep[y]-dep[lca];
}
printf("%lld\n",ans);
return 0;
}

  


By NeighThorn

BZOJ 3910: 火车的更多相关文章

  1. BZOJ 3910 火车 倍增LCA

    本题并不需要并查集,每次查询一次最近公共祖先,并倍增求出需要被新标记的路径. 这样保证时间复杂度是 O(nlogn)O(nlogn)O(nlogn) 的. Code: #include<cstd ...

  2. BZOJ 3910 并查集+线段树合并

    思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...

  3. 【BZOJ-3910】火车 倍增LCA + 并查集

    3910: 火车 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 262  Solved: 90[Submit][Status][Discuss] De ...

  4. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  5. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  6. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  7. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  8. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  9. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

随机推荐

  1. mysql安装记录

    一.创建mysql用户 useradd mysql 二.解压 tar -zxvf mysql-5.6.38.tar.gz 三.安装依赖包 yum install -y ncurses-devel li ...

  2. Freemaker基于word模板动态导出汇总整理

    Freemaker基于word模板动态导出汇总整理 一.使用的jar包: 二.Word模板动态导出的基本思路: 1.首先通过自己在word中创建好需要导出的word文本+表格的模板,模板中需要填写内容 ...

  3. 绘制圆形 和 椭圆形:边圆形 imageellipse() 、 填充圆形imagefilledellipse()

    <?php //1. 绘制图像资源(创建一个画布) $image = imagecreatetruecolor(500, 300); //2. 先分配一个绿色 $green = imagecol ...

  4. debug模式开启会做哪些事(源码分析)

    以往开发中不管是django框架下开发还是其它框架下开发, 只知道在开发阶段要开启debug模式, 却一直没有深究它会我们做哪些事, 今天使用tornado时偶然看到源码中写的很清楚,故写下来加深印象 ...

  5. POJ 2586 贪心+枚举

    Y2K Accounting Bug Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15626   Accepted: 78 ...

  6. 网络抢票黄牛,大部分是骗人的。公布一个骗钱黄牛,QQ:2233261390,QQ群:29443597,支付页面:https://me.alipay.com/q336

    想着给女友买张回广州的回程火车票,抢了3天也没弄到.情急之下找了网络上所谓的黄牛.结果上当受骗.具体经过是这样的: 对方承诺抢到再付款.于是等他抢到后截图给我看,而且可以远程到他的机器去看,我也确实远 ...

  7. loj2537 「PKUWC 2018」Minimax

    pkusc 快到了--做点题涨涨 rp. 初见时 yy 了一个类似于归并的东西,\(O(n^2)\),50 分. 50 分 yy 做法 对于一个点,枚举他能到达的权值(假设这个权值在左子树,在右子树是 ...

  8. SPFA - Luogu 3385 【模板】负环

    [模板]负环 描述 找负环 输入 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个顶点,M条边 接下来M行,每行三个整数a b w,表示a->b有一条权值为w ...

  9. 成为谷歌的java程序员首先要做到这五点!

    成为谷歌的java程序员首先要做到这五点! 在现在,就是现在,程序员称霸武林,但是这是一个现实的社会,并没有天下第一这么一说,总是人外有人山外有山,想要成为谷歌程序员,你还要听听谷歌员工给的5个重要建 ...

  10. Linux之如何进行固定IP、DNS等设置

    前提:虚拟机Linux centOS6.6 Linux如何设置固定IP.dns.网关 1.切换到root账号 2.#cd  /etc/sysconfig/network-scripts 进入网卡的设置 ...