【BZOJ3611】大工程(虚树,DFS序,树形DP)
题意:有一棵树,树有边权,有若干次询问,给出一些点,求:
1.这些点互相之间的距离之和
2.点对距离中的最大和最小值
n<=1000000
var head,vet,next,len,
head1,vet1,next1,len1,
h,stk,b,dep,dfn,flag,c:array[..]of longint;
dp:array[..,..]of longint;
size,g:array[..]of int64;
f:array[..,..]of longint;
n,i,tot,que,ans1,ans2,time,x,y:longint;
ans:int64; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; function min(x,y:int64):int64;
begin
if x<y then exit(x);
exit(y);
end; function max(x,y:int64):int64;
begin
if x>y then exit(x);
exit(y);
end; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; procedure qsort(l,r:longint);
var i,j,mid:longint;
begin
i:=l; j:=r; mid:=b[(l+r)>>];
repeat
while mid>b[i] do inc(i);
while mid<b[j] do dec(j);
if i<=j then
begin
swap(h[i],h[j]);
swap(b[i],b[j]);
inc(i); dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end; function lca(x,y:longint):longint;
var i,d:longint;
begin
if dep[x]<dep[y] then swap(x,y);
d:=dep[x]-dep[y];
for i:= to do
if d and (<<i)> then x:=f[x,i];
for i:= downto do
if f[x,i]<>f[y,i] then
begin
x:=f[x,i]; y:=f[y,i];
end;
if x=y then exit(x);
exit(f[x,]);
end; procedure dfs(u:longint);
var e,v,i:longint;
begin
for i:= to do
begin
if dep[u]<(<<i) then break;
f[u,i]:=f[f[u,i-],i-];
end;
inc(time); dfn[u]:=time;
flag[u]:=;
e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
f[v,]:=u;
dep[v]:=dep[u]+;
dfs(v);
end;
e:=next[e];
end;
end; procedure add1(a,b:longint);
begin
if a=b then exit;
inc(tot);
next1[tot]:=head1[a];
vet1[tot]:=b;
len1[tot]:=abs(dep[a]-dep[b]);
head1[a]:=tot;
end; procedure dfs2(u:longint);
var e,v:longint;
begin
size[u]:=c[u];
g[u]:=;
if c[u]= then begin dp[u,]:=; dp[u,]:=; end
else begin dp[u,]:=-maxlongint div ; dp[u,]:=maxlongint div ; end;
e:=head1[u];
while e<> do
begin
v:=vet1[e];
dfs2(v);
ans:=ans+size[v]*g[u]+size[u]*g[v]+size[u]*size[v]*len1[e];
size[u]:=size[u]+size[v];
g[u]:=g[u]+g[v]+size[v]*len1[e];
ans1:=max(ans1,dp[u,]+dp[v,]+len1[e]);
ans2:=min(ans2,dp[u,]+dp[v,]+len1[e]);
dp[u,]:=max(dp[u,],dp[v,]+len1[e]);
dp[u,]:=min(dp[u,],dp[v,]+len1[e]);
e:=next1[e];
end;
head1[u]:=;
end; procedure solve;
var q,top,i,now,m,p:longint;
begin
tot:=;
read(m);
for i:= to m do
begin
read(h[i]); b[i]:=dfn[h[i]];
c[h[i]]:=;
end;
qsort(,m);
//q:=;
//for i:= to m do
//if lca(h[i],h[q])<>h[q] then begin inc(q); h[q]:=h[i]; end;
stk[]:=; top:=;
for i:= to m do
begin
now:=h[i]; p:=lca(now,stk[top]);
while true do
begin
if dep[p]>=dep[stk[top-]] then
begin
add1(p,stk[top]); dec(top);
if stk[top]<>p then begin inc(top); stk[top]:=p; end;
break;
end;
add1(stk[top-],stk[top]); dec(top);
end;
if stk[top]<>now then begin inc(top); stk[top]:=now; end;
end;
for i:=top- downto do add1(stk[i],stk[i+]);
ans:=; ans1:=-maxlongint div ; ans2:=maxlongint div ;
dfs2();
writeln(ans,' ',ans2,' ',ans1);
for i:= to m do c[h[i]]:=;
end; begin readln(n);
for i:= to n- do
begin
readln(x,y);
add(x,y,);
add(y,x,);
end;
dfs();
readln(que);
for i:= to que do solve; end.
var head,vet,next,len,
head1,vet1,next1,len1,
h,stk,b,dep,dfn,flag,c,d:array[..]of longint;
dp:array[..,..]of longint;
size,g:array[..]of int64;
f:array[..,..]of longint;
n,i,tot,que,ans1,ans2,time,x,y:longint;
ans:int64; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; function min(x,y:int64):int64;
begin
if x<y then exit(x);
exit(y);
end; function max(x,y:int64):int64;
begin
if x>y then exit(x);
exit(y);
end; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; procedure qsort1(l,r:longint);
var i,j,mid:longint;
begin
i:=l; j:=r; mid:=b[(l+r)>>];
repeat
while mid>b[i] do inc(i);
while mid<b[j] do dec(j);
if i<=j then
begin
swap(h[i],h[j]);
swap(b[i],b[j]);
inc(i); dec(j);
end;
until i>j;
if l<j then qsort1(l,j);
if i<r then qsort1(i,r);
end; procedure qsort2(l,r:longint);
var i,j,mid:longint;
begin
i:=l; j:=r; mid:=b[(l+r)>>];
repeat
while mid>b[i] do inc(i);
while mid<b[j] do dec(j);
if i<=j then
begin
swap(d[i],d[j]);
swap(b[i],b[j]);
inc(i); dec(j);
end;
until i>j;
if l<j then qsort2(l,j);
if i<r then qsort2(i,r);
end; function lca(x,y:longint):longint;
var i,d:longint;
begin
if dep[x]<dep[y] then swap(x,y);
d:=dep[x]-dep[y];
for i:= to do
if d and (<<i)> then x:=f[x,i];
for i:= downto do
if f[x,i]<>f[y,i] then
begin
x:=f[x,i]; y:=f[y,i];
end;
if x=y then exit(x);
exit(f[x,]);
end; procedure dfs(u:longint);
var e,v,i:longint;
begin
for i:= to do
begin
if dep[u]<(<<i) then break;
f[u,i]:=f[f[u,i-],i-];
end;
inc(time); dfn[u]:=time;
flag[u]:=;
e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
f[v,]:=u;
dep[v]:=dep[u]+;
dfs(v);
end;
e:=next[e];
end;
end; procedure add1(a,b:longint);
begin
if a=b then exit;
inc(tot);
next1[tot]:=head1[a];
vet1[tot]:=b;
len1[tot]:=abs(dep[a]-dep[b]);
head1[a]:=tot;
end; procedure dfs2(u:longint);
var e,v:longint;
begin
size[u]:=c[u];
g[u]:=;
if c[u]= then begin dp[u,]:=; dp[u,]:=; end
else begin dp[u,]:=-maxlongint div ; dp[u,]:=maxlongint div ; end;
e:=head1[u];
while e<> do
begin
v:=vet1[e];
dfs2(v);
ans:=ans+size[v]*g[u]+size[u]*g[v]+size[u]*size[v]*len1[e];
size[u]:=size[u]+size[v];
g[u]:=g[u]+g[v]+size[v]*len1[e];
ans1:=max(ans1,dp[u,]+dp[v,]+len1[e]);
ans2:=min(ans2,dp[u,]+dp[v,]+len1[e]);
dp[u,]:=max(dp[u,],dp[v,]+len1[e]);
dp[u,]:=min(dp[u,],dp[v,]+len1[e]);
e:=next1[e];
end;
head1[u]:=;
end; procedure solve;
var q,top,i,now,m,p:longint;
begin
tot:=;
read(m);
for i:= to m do
begin
read(h[i]); b[i]:=dfn[h[i]];
c[h[i]]:=;
end;
qsort1(,m);
q:=;
for i:= to m do
begin
inc(q); d[q]:=h[i]; flag[h[i]]:=;
end;
for i:= to m- do
begin
p:=lca(h[i],h[i+]);
if flag[p]= then begin flag[p]:=; inc(q); d[q]:=p; end;
end;
for i:= to q do b[i]:=dfn[d[i]];
qsort2(,q); stk[]:=d[]; top:=;
for i:= to q do
begin
x:=d[i];
while true do
begin
y:=stk[top];
if lca(x,y)<>y then dec(top)
else
begin
add1(y,x);
break;
end;
end;
inc(top); stk[top]:=x;
end; ans:=; ans1:=-maxlongint div ; ans2:=maxlongint div ;
dfs2(d[]);
writeln(ans,' ',ans2,' ',ans1);
for i:= to m do c[h[i]]:=;
for i:= to q do flag[d[i]]:=;
end; begin
assign(input,'bzoj3611.in'); reset(input);
assign(output,'bzoj3611.out'); rewrite(output);
readln(n);
for i:= to n- do
begin
readln(x,y);
add(x,y,);
add(y,x,);
end;
dfs();
readln(que);
fillchar(flag,sizeof(flag),);
for i:= to que do solve;
close(input);
close(output);
end.
【BZOJ3611】大工程(虚树,DFS序,树形DP)的更多相关文章
- [HEOI2014][bzoj3611] 大工程 [虚树+dp]
题面: 传送门 思路: 又是一道虚树入门级的题目,但是这道题的实际难点在于dp 首先,这道题是可以点分治做的,而且因为6s时限随便浪,所以写点分治也不是不可以 但是,dp因为$O\left(n\rig ...
- 【BZOJ】3991: [SDOI2015]寻宝游戏 虚树+DFS序+set
[题意]给定n个点的带边权树,对于树上存在的若干特殊点,要求任选一个点开始将所有特殊点走遍后返回.现在初始没有特殊点,m次操作每次增加或减少一个特殊点,求每次操作后的总代价.n,m<=10^5. ...
- [JSOI2016]最佳团体 DFS序/树形DP
题目 洛谷 P4322 [JSOI2016]最佳团体 Description 茜茜的舞蹈团队一共有\(N\)名候选人,这些候选人从\(1\)到\(N\)编号.方便起见,茜茜的编号是\(0\)号.每个候 ...
- luogu P4103 [HEOI2014]大工程 虚树 + 树形 DP
Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通 ...
- 洛谷P4103 [HEOI2014]大工程(虚树 树形dp)
题意 链接 Sol 虚树. 首先建出虚树,然后直接树形dp就行了. 最大最小值直接维护子树内到该节点的最大值,然后合并两棵子树的时候更新一下答案. 任意两点的路径和可以考虑每条边两边的贡献,\(d[x ...
- BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)
题目链接 要求的和.最大值.最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n. 于是建虚树就可以了.具体DP见DP()函数,维护三个值sum[],mx[],mn[]. sum[]要开 ...
- bzoj 3611: [Heoi2014]大工程 虚树
题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...
- 【HEOI2014】大工程<虚树>
虚树 我们每天都用心思索着,这究竟是为了什么呢?我想我也不知道,只是觉得如果人不思考问题就很无聊. 我觉得虚树不是什么数据结构,就是一种技巧或者工具.它能把树中\(k\)个关键点以\(O(klogk) ...
- bzoj 3611(洛谷 4103) [Heoi2014]大工程——虚树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3611 https://www.luogu.org/problemnew/show/P4103 ...
- BZOJ 3611 [Heoi2014]大工程 ——虚树
虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...
随机推荐
- SAP CRM中间件下载equipment时遇到的一个错误
在CRM开发系统上进行equipment下载,发现不工作.调试发现错误信息在下图定96行的WHEN default分支抛出的: MESSAGE ID 'AZ' ... 通过阅读源代码发现,ERP端支持 ...
- Docker镜像的目录存储讲解
我们成功安装完docker后,执行命令行sudo docker run hello-world, 如果是第一次执行,则会从远程拉取hello-world的镜像到本地,然后运行,显示hello worl ...
- (转)MyBatis框架的学习(二)——MyBatis架构与入门
http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图: 下面作简要概述: S ...
- HDU 6166 Senior Pan(多校第九场 二进制分组最短路)
题意:给出n个点和m条有向边(有向边!!!!我还以为是无向查了半天),然后给出K个点,问这k个点中最近的两点的距离 思路:比赛时以为有询问,就直接丢了,然后这题感觉思路很棒,加入把所有点分成起点和终点 ...
- Java——舞动的排序
一.冒泡排序: http://v.youku.com/v_show/id_XMzMyOTAyMzQ0.html //冒泡排序 public class Bubbling { public static ...
- Hibernate 中批量处理数据
一.批量处理操作 批量处理数据是指在一个事务场景中处理大量数据.在应用程序中难以避免进行批量操作,Hibernate提供了以下方式进行批量处理数据: (1)使用HQL进行批量操作 数据库层面 ...
- Python-DB接口规范
threadsafety 线程安全级别.threadsafety 这是一个整数, 取值范围如下: 0:不支持线程安全, 多个线程不能共享此模块 1:初级线程安全支持: 线程可以共享模块, 但不能共享连 ...
- WinPcap过滤串表达式的语法
注意:这篇文档取自tcpdump的指南.原始的版本 www.tcpdump.org 找到. wpcap的过滤器是以已声明的谓词语法为基础的.过滤器是一个ASCII字符串,它包含了一个过滤表达式.p ...
- 基于IMD的包过滤防火墙原理与实现
一.前言二.IMD中间层技术介绍三.passthru例程分析四.部分演示代码五.驱动编译与安装六. 总结 一.前言 前段时间,在安全焦点上看到了TOo2y朋友写的<基于SPI的数据报过滤原理与实 ...
- web资源持续更新----20150213
响应式设计创意收集网站:http://mediaqueri.es css禅意花园 http://www.csszengarden.com/