bzoj 3910 并查集+LCA
来源:互联网 发布:乐视没有mac版 编辑:程序博客网 时间:2024/06/05 17:20
题意:给出一棵树,给定起点和要经过的点的序列,已经经过的点就不去了,即在剩下的点中按照顺序依次去访问还没有访问过的点,问要经过多少条边。
很显然的一个做法就是每当我们走一条路径的时候,就把这条路径上所有点都打上已经被经过的标记,对于一个点,如果它的标记为真则不用再走。
所以复杂度高的原因就是一些点会被来回来去的多次被标记,每次处理的复杂度都是O(n)的
但实际上只要一个点被打上标记就不用再管它了,直接找到路径上下一个没有被打过标记的位置
这不就和bzoj 2054 一毛一样了么
所以每当我们走一条新的路径,就用并查集把这一段路径缩成一个大点,用这两个点的lca做并查集的根,
这样就可以保证每个点最多被标记一次
当然算经过的边的时候还是要按原树跳的
{$Q-}var n,m,pl,x,l,y :longint; ans :int64; i,j :longint; jump :array[0..500010,0..20] of longint; d,que :array[0..500010] of longint; last,father,from:array[0..500010] of longint; vis,flag :array[0..500010] of boolean; pre,other :array[0..1000010] of longint;procedure swap(var a,b:longint);var c:longint;begin c:=a; a:=b; b:=c;end;function get_father(x:longint):longint;begin if x=father[x] then exit(x); father[x]:=get_Father(father[x]); exit(father[x]);end;procedure connect(x,y:longint);begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y;end;procedure dfs(x:longint);var p,q:longint;begin q:=last[x]; while q<>0 do begin p:=other[q]; if not vis[p] then begin from[p]:=x; vis[p]:=true; jump[p,0]:=x; d[p]:=d[x]+1; dfs(p); end; q:=pre[q]; end;end;function lca(x,y:longint):int64;var i:longint; ans:int64;begin ans:=0; if d[x]>d[y] then swap(x,y); for i:=0 to 20 do if ((d[y]-d[x]) and (1<<i) <>0) then begin inc(ans,1<<i); y:=jump[y,i]; end; if x=y then exit(ans); for i:=20 downto 0 do if jump[x,i]<>jump[y,i] then begin inc(ans,1<<i); inc(ans,1<<i); x:=jump[x,i]; y:=jump[y,i]; end; inc(ans,2); exit(ans);end;procedure work(x,y:longint);var tl,tt:longint;begin tl:=0; while x<>y do begin if d[x]>d[y] then swap(x,y); inc(tl); que[tl]:=y; flag[y]:=true; y:=get_father(from[y]); end; flag[x]:=true; while tl>0 do begin father[get_father(que[tl])]:=x; dec(tl); end;end;begin read(n,m,pl); for i:=1 to n-1 do begin read(x,y); connect(x,y); connect(y,x); end; vis[1]:=true; d[1]:=1; dfs(1); // for j:=1 to 20 do for i:=1 to n do jump[i,j]:=jump[jump[i,j-1],j-1]; for i:=1 to n do father[i]:=i; for i:=1 to m do begin read(x); if not flag[x] then begin inc(ans,lca(x,pl)); work(get_father(pl),x); pl:=x; end; end; writeln(ans);end.——by Eirlys
0 0
- BZOJ 3910 火车 LCA+并查集
- BZOJ 3910: 火车|LCA|并查集
- bzoj 3910 并查集+LCA
- bzoj 3910(LCA+并查集)
- 3910: 火车 LCA+并查集
- poj3728并查集+LCA
- 【BZOJ 3910】火车 并查集
- LCA算法--并查集应用
- poj 3728(LCA+并查集应用)
- HDU2874并查集+(LCA-RMQ)
- POJ_3694 Network Tarjin + LCA + 并查集
- LCA Tarjin 并查集 离线
- poj3728 The merchant LCA+并查集
- POJ 3694 Network lca + 并查集
- hdu 2586(LCA+并查集)
- 【BZOJ3910】火车 LCA+并查集
- LCA离线算法Tarjan+并查集
- hdu5458 LCA+并查集+树状数组
- 2017新版微信红包牛牛 接龙 扫雷游戏程序运营版分享
- 【信息安全】对称加密与非对称加密
- 面向对象
- 分治算法---二分搜索算法
- 产品经理如何来优化CSDN手机短信验证的功能
- bzoj 3910 并查集+LCA
- 【CEGUI】CEGUI入门篇之初始化(一)
- 113.Test测试实现黑名单的增删该查
- 【CEGUI】CEGUI入门篇之使用ResourceProvider加载资源(二)
- 【CEGUI】CEGUI入门篇之数据文件及默认初始化(三)
- 数据字段属性
- kmp 算法
- ROS学习(基于Ubuntu 15.04 和ROS Jade)第三章 ROS核心教程 之 5 理解ROS节点
- 投资案例分析:投资创业公司时,VC 关注什么?