题意

建出虚树DP。

设\(f[i]\)表示i的子树的第一问答案,\(minn[i]\)表示\(i\)的子树中到\(i\)最近的关键点,\(maxx[i]\)表示\(i\)的子树中到i距离最远的关键点,\(size[i]\)表示\(i\)子树中的关键点个数。

\(f[x]=\sum\limits_{y\in\ son_x}f[y]+size[y]*(tot-size[y])*w\)

\(minn\)和\(maxx\)就类似树的直径。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000010;
const ll inf=1e18;
int n,m,cnt,t,top,tot,tim;
int head[maxn],size[maxn],a[maxn],dep[maxn],sta[maxn],dfn[maxn];
int f[maxn][25];
ll ans1,ans2;
ll g[maxn],maxx[maxn],minn[maxn];
bool check[maxn];
struct edge{int to,nxt,dis;}e[maxn<<1];
inline int read()
{
char c=getchar();int res=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
return res*f;
}
inline bool cmp(int x,int y){return dfn[x]<dfn[y];}
inline void add(int u,int v,int w)
{
e[++cnt].nxt=head[u];
head[u]=cnt;
e[cnt].to=v;
e[cnt].dis=w;
}
void dfs_pre(int x,int fa)
{
dep[x]=dep[fa]+1;dfn[x]=++tim;
for(int i=1;i<=t;i++)f[x][i]=f[f[x][i-1]][i-1];
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(y==fa)continue;
f[y][0]=x;dfs_pre(y,x);
}
}
inline int lca(int x,int y)
{
if(dep[x]>dep[y])swap(x,y);
for(int i=t;~i;i--)if(dep[f[y][i]]>=dep[x])y=f[y][i];
if(x==y)return x;
for(int i=t;~i;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][0];
}
inline int dis(int x,int y){return dep[x]+dep[y]-2*dep[lca(x,y)];}
void dfs(int x)
{
//cerr<<"test::"<<x<<endl;
g[x]=0;
maxx[x]=-inf,minn[x]=inf;size[x]=0;
if(check[x])size[x]=1,minn[x]=0,maxx[x]=0;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
dfs(y);size[x]+=size[y];
g[x]+=g[y]+1ll*e[i].dis*size[y]*(tot-size[y]);
ans1=min(ans1,minn[x]+minn[y]+e[i].dis);
minn[x]=min(minn[x],minn[y]+e[i].dis);
ans2=max(ans2,maxx[x]+maxx[y]+e[i].dis);
maxx[x]=max(maxx[x],maxx[y]+e[i].dis);
}
}
void solve()
{
cnt=0;ans1=inf;ans2=-inf;
tot=read();
for(int i=1;i<=tot;i++)a[i]=read(),check[a[i]]=1;
sort(a+1,a+tot+1,cmp);
sta[top=1]=1,head[1]=0;
for(int i=1;i<=tot;i++)
{
if(a[i]==1)continue;
int x=lca(a[i],sta[top]);
if(x!=sta[top])
{
while(top>1&&dfn[sta[top-1]]>dfn[x])add(sta[top-1],sta[top],dis(sta[top-1],sta[top])),top--;
if(x!=sta[top-1])head[x]=0,add(x,sta[top],dis(x,sta[top])),sta[top]=x;
else add(x,sta[top],dis(x,sta[top])),top--;
}
head[a[i]]=0;sta[++top]=a[i];
}
for(int i=1;i<top;i++)add(sta[i],sta[i+1],dis(sta[i],sta[i+1]));
dfs(1);
printf("%lld %lld %lld\n",g[1],ans1,ans2);
for(int i=1;i<=tot;i++)check[a[i]]=0;
}
int main()
{
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
n=read();t=(int)log2(n)+1;
for(int i=1;i<n;i++)
{
int u=read(),v=read();
add(u,v,1),add(v,u,1);
}
dfs_pre(1,0);
m=read();
for(int i=1;i<=m;i++)solve();
return 0;
}

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

  1. [BZOJ3611][Heoi2014]大工程

    [BZOJ3611][Heoi2014]大工程 试题描述 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上.  在 ...

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

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

  3. 【LG4103】[HEOI2014]大工程

    [LG4103][HEOI2014]大工程 题面 洛谷 题解 先建虚树,下面所有讨论均是在虚树上的. 对于第一问:直接统计所有树边对答案的贡献即可. 对于第\(2,3\)问:记\(f[x]\)表示在\ ...

  4. 3611: [Heoi2014]大工程

    3611: [Heoi2014]大工程 链接 分析: 树形dp+虚树. 首先建立虚树,在虚树上dp. dp:sum[i]为i的子树中所有询问点之间的和.siz[i]为i的子树中有多少询问点,mn[i] ...

  5. P4103 [HEOI2014]大工程

    题目 P4103 [HEOI2014]大工程 化简题目:在树上选定\(k\)个点,求两两路径和,最大的一组路径,最小的一组路径 做法 关键点不多,建个虚树跑一边就好了 \(sum_i\)为\(i\)子 ...

  6. BZOJ2286 [Sdoi2011]消耗战 和 BZOJ3611 [Heoi2014]大工程

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6371  Solved: 2496[Submit][Statu ...

  7. 【BZOJ3611】[Heoi2014]大工程 欧拉序+ST表+单调栈

    [BZOJ3611][Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶 ...

  8. [Bzoj3611][Heoi2014]大工程(虚树)

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

  9. [BZOJ3611][Heoi2014]大工程(虚树上DP)

    3611: [Heoi2014]大工程 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 2464  Solved: 1104[Submit][Statu ...

随机推荐

  1. Linux系统中的截图功能(类似QQ、微信、Snipaste截图功能)

    作者亲笔测试Ubuntu16.04,18.04,deepin15.11桌面版本Linux内核系统. 安装: 1. 终端命令黑框 2. sudo apt-get install flameshot(体积 ...

  2. 重装windows后如何恢复mysql服务

    如果重装系统后之前的mysql还在的话,可又直接恢复,不需要安装: 注意my.ini文件的位置,应该与bin目录同级: 进入cmd,然后进入你的mysql的bin目录,输入命令:mysqld inst ...

  3. Educational Codeforces Round 76 (Rated for Div. 2) B. Magic Stick 水题

    B. Magic Stick Recently Petya walked in the forest and found a magic stick. Since Petya really likes ...

  4. vue表格合并行的一个实例

        一.element控件实现 在平常的应用中,需要用到合并单元格的操作,在Excel中,这种操作很好实现,但在实际项目中,常常需要借助element控件来实现. 下面是element中的一个实例 ...

  5. Mysql如何在删库后可以不用跑路

    我一直在想,地球上这么多程序员,应该有很多人在团队做项目的时候,出过很大的错误,比如说不小心删了库,活动福利字段多写了个零导致全服务器玩家领到数倍奖励,听了沙雕群友的话执行rm -rf命令. 记得有一 ...

  6. 创意编程,Python开发多功能壁纸自动切换工具!

    import ctypes import time import requests import os from threading import Thread from tkinter import ...

  7. 1+x证书web前端开发jquery专项练习测试题

    javascript程序设计-题库 1.下面哪一种不属于Jquery的选择器? A. 基本选择器 B. 层次选择器 C. 表单选择器 D. 节点选择器 答案: D 2.如果需要匹配包含文本的元素,用下 ...

  8. 微信小程序反编译

    看到一个有意思的小程序,想了解是如何实现的,于是找了反编译方法. 安装adb驱动 百度安装adb驱动, 设计设置开发者模式,连接电脑. -> % adb devices List of devi ...

  9. jvm 性能调优工具之 jstat

    概述 Jstat是JDK自带的一个轻量级小工具.全称“Java Virtual Machine statistics monitoring tool”,它位于java的bin目录下,主要利用JVM内建 ...

  10. 模型可视化工具netron

    https://github.com/lutzroeder/Netron 支持各种格式的模型 caffe模型实测效果: 右侧可以看到卷积核的具体的值.