题目描述

国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。

我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。

在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a,b 的最短路径。

现在国家有很多个计划,每个计划都是这样,我们选中了 k 个点,然后在它们两两之间 新建 C(k,2)条 新通道。现在对于每个计划,我们想知道: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少

输入输出格式

输入格式:

第一行 n 表示点数。

接下来 n-1 行,每行两个数 a,b 表示 a 和 b 之间有一条边。点从 1 开始标号。

接下来一行 q 表示计划数。对每个计划有 2 行,第一行 k 表示这个计划选中了几个点。

第二行用空格隔开的 k 个互不相同的数表示选了哪 k 个点。

输出格式:

输出 q 行,每行三个数分别表示代价和,最小代价,最大代价。

输入输出样例

输入样例#1: 复制

10
2 1
3 2
4 1
5 2
6 4
7 5
8 6
9 7
10 9
5
2
5 4
2
10 4
2
5 2
2
6 1
2
6 1
输出样例#1: 复制

3 3 3
6 6 6
1 1 1
2 2 2 2 2 2

说明

对于第 1,2 个点: n<=10000

对于第 3,4,5 个点: n<=100000,交通网络构成一条链

对于第 6,7 个点: n<=100000

对于第 8,9,10 个点: n<=1000000

对于所有数据, q<=50000并且保证所有k之和<=2*n

看到k的和小于2*n,于是立刻想到建虚树

建出虚树后就dp

size[x]表示x的子树中关键点数

f[x]表示x子树中路径的贡献和

Min[x]表示x子树中离x距离最小的关键点的距离

Max[x]表示最大的距离

最大值和求和很简单

最大值总是要取到叶子节点,虚树中叶子节点总是关键点

答案取当前Max[x]+Max[v]+边权w,然后Max[x]=max(Max[x],Max[v]+d)

求和就考虑一条边的贡献

一条边的贡献次数显然是size[v]*(k-size[v])

所以f[x]+=f[v]+size[v]*(k-size[v])*w

求最小值的话,Min[x]初值正无穷

如果是关键点就直接取它的子树路径最小值,否则就是它的两个儿子的子树路径最小值相加

如果是关键点,更新答案后Min[x]要清0,作为接下来的端点

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
const int N=;
struct Node
{
int next,to;
}edge[N],edge2[N];
int inf=1e9;
int dep[N],fa[N][],dfn[N],cnt,bin[],head[N],head2[N],num,ed[N];
int size[N],vis[N],Max[N],Min[N],k,M,ans1,ans2,n,Lca,a[N],s[N],top;
lol f[N];
int gi()
{
char ch=getchar();
int x=;
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='')
{
x=x*+ch-'';
ch=getchar();
}
return x;
}
bool cmp(int a,int b)
{
return dfn[a]<dfn[b];
}
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void add2(int u,int v)
{
if (u==v) return;
num++;
edge2[num].next=head2[u];
head2[u]=num;
edge2[num].to=v;
}
void dfs(int x,int pa)
{int i;
dep[x]=dep[pa]+;
dfn[x]=++cnt;
for (i=;bin[i]<=dep[x];i++)
fa[x][i]=fa[fa[x][i-]][i-];
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa) continue;
fa[v][]=x;
dfs(v,x);
}
ed[x]=cnt;
}
int lca(int x,int y)
{int as,i;
if (dep[x]<dep[y]) swap(x,y);
for (i=;i>=;i--)
if (bin[i]<=dep[x]-dep[y])
x=fa[x][i];
if (x==y) return x;
for (i=;i>=;i--)
{
if (fa[x][i]!=fa[y][i])
{
x=fa[x][i];y=fa[y][i];
}
}
return fa[x][];
} void dp(int x)
{int i;
size[x]=vis[x];
Max[x]=;Min[x]=inf;f[x]=;
for (i=head2[x];i;i=edge2[i].next)
{
int v=edge2[i].to,d=dep[v]-dep[x];
dp(v);
size[x]+=size[v];
f[x]+=f[v]+1ll*size[v]*(k-size[v])*d;
ans1=min(ans1,Min[x]+Min[v]+d);Min[x]=min(Min[x],Min[v]+d);
ans2=max(ans2,Max[x]+Max[v]+d);Max[x]=max(Max[x],Max[v]+d);
}
if (vis[x]) ans1=min(ans1,Min[x]),ans2=max(ans2,Max[x]),Min[x]=;
}
int main()
{int i,u,v,j,q;
cin>>n;
bin[]=;
for (i=;i<=;i++)
bin[i]=bin[i-]*;
for (i=;i<=n-;i++)
{
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(,);
cin>>q;
while (q--)
{
k=gi();
M=k;
num=;ans1=inf;ans2=;
for (i=;i<=k;i++)
a[i]=gi(),vis[a[i]]=;
sort(a+,a+k+,cmp);
Lca=a[];
for (i=;i<=k;i++)
if (ed[a[i-]]<dfn[a[i]])
a[++M]=lca(a[i-],a[i]),Lca=lca(Lca,a[i]);
a[++M]=Lca;
sort(a+,a+M+,cmp);
M=unique(a+,a+M+)-a-;
s[++top]=a[];
for (i=;i<=M;i++)
{
while (top&&ed[s[top]]<dfn[a[i]]) top--;
add2(s[top],a[i]);
s[++top]=a[i];
}
dp(Lca);
printf("%lld %d %d\n",f[Lca],ans1,ans2);
for (i=;i<=M;i++)
vis[a[i]]=head2[a[i]]=;
}
}

[HEOI2014]大工程的更多相关文章

  1. bzoj 3611: [Heoi2014]大工程 虚树

    题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...

  2. luogu P4103 [HEOI2014]大工程 虚树 + 树形 DP

    Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上.  在 2 个国家 a,b 之间建一条新通 ...

  3. 洛谷P4103 [HEOI2014]大工程(虚树 树形dp)

    题意 链接 Sol 虚树. 首先建出虚树,然后直接树形dp就行了. 最大最小值直接维护子树内到该节点的最大值,然后合并两棵子树的时候更新一下答案. 任意两点的路径和可以考虑每条边两边的贡献,\(d[x ...

  4. bzoj 3611(洛谷 4103) [Heoi2014]大工程——虚树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3611 https://www.luogu.org/problemnew/show/P4103 ...

  5. BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)

    题目链接 要求的和.最大值.最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n. 于是建虚树就可以了.具体DP见DP()函数,维护三个值sum[],mx[],mn[]. sum[]要开 ...

  6. BZOJ 3611 [Heoi2014]大工程 ——虚树

    虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...

  7. bzoj 3611[Heoi2014]大工程 虚树+dp

    题意: 给一棵树 每次选 k 个关键点,然后在它们两两之间 新建 C(k,2)条 新通道. 求: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少 分析:较常 ...

  8. 【HEOI2014】大工程<虚树>

    虚树 我们每天都用心思索着,这究竟是为了什么呢?我想我也不知道,只是觉得如果人不思考问题就很无聊. 我觉得虚树不是什么数据结构,就是一种技巧或者工具.它能把树中\(k\)个关键点以\(O(klogk) ...

  9. [HEOI2014][bzoj3611] 大工程 [虚树+dp]

    题面: 传送门 思路: 又是一道虚树入门级的题目,但是这道题的实际难点在于dp 首先,这道题是可以点分治做的,而且因为6s时限随便浪,所以写点分治也不是不可以 但是,dp因为$O\left(n\rig ...

  10. bzoj 3611 [Heoi2014]大工程(虚树+DP)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 408  Solved: 190[Submit][Status] ...

随机推荐

  1. hibernate框架学习笔记11:Criteria查询详解

    创建实体类对象: package domain; import java.util.HashSet; import java.util.Set; //客户实体 public class Custome ...

  2. alpha-咸鱼冲刺day3

    一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 今天把数据库的表给建好了,学长那边把登陆跟注册页面也做好了(纯页面,html5+css的那种) 四,问题困难 日常啥都不会,百度 ...

  3. java封装的概念

    继承.封装.多态.抽象是面向对象编程的四大基本概念,其中封装尤为重要,因为从我们学习JAVA开始,就基本上接触了封装,因为JAVA中的所有程序都是写在类中的,类也能当做一种封装. 在面向对象中封装是指 ...

  4. 201621123031 《Java程序设计》第13周学习总结

    作业13-网络 1.本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被 ...

  5. Linux 下的权限改变与目录配置

    Linux 下的权限改变与目录配置 ./代表本目录的意思. (1):用户与用户组, 1:文件所有者,文件被某一用户所有 2:用户组:    对文件给与一个或者多个用户权限配置 3:其它人: (2):l ...

  6. bzoj千题计划271:bzoj4869: [六省联考2017]相逢是问候

    http://www.lydsy.com/JudgeOnline/problem.php?id=4869 欧拉降幂+线段树,每个数最多降log次,模数就会降为1 #include<cmath&g ...

  7. C# 一个初学者对 依赖注入 IOC 的理解( 含 Unity 的使用)

    通过 人打电话 来谈谈自己对IOC的理解 版本1.0 public class Person { public AndroidPhone Phone { get; set; } public void ...

  8. Python内置函数(37)——sorted

    英文文档: sorted(iterable[, key][, reverse]) Return a new sorted list from the items in iterable. Has tw ...

  9. dubbo的InvocationChain

    个人觉得dubbo比较好的设计是:一个是Cooma微容器设计.另一个就是InvocationChain了 Cooma微容器是自己实现了一套SPI,方便了用户做扩展: InvocationChain类似 ...

  10. SQL server2017的操作(练习题)

    题目: 假设有教材管理数据库BM,包括3个基本表: 教材(书号,书名,作者,出版社) B(Bno, Bname, Author, pub) 班级(班号,专业,所在系,人数) C(Cno, Spe, D ...