题目


分析

建一棵虚树,然后树形dp,维护最长/短链和次长/短链,

对于第一个就是统计每条边有多少个点对经过就可以了


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=1000011; long long ans1; int ans2,a[N],ans3,mm;
struct node{int y,next;}e[N<<1],E[N]; int stac[N],hs[N],mn[N][2],mx[N][2],v[N];
int dep[N],fat[N],siz[N],as[N],Siz[N],W[N],big[N],dfn[N],tot,Top[N],n,et=1,Et,m;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,fat[x]=fa,siz[x]=1;
for (rr int i=as[x],SIZ=-1;i;i=e[i].next)
if (e[i].y!=fa){
dfs1(e[i].y,x),siz[x]+=siz[e[i].y];
if (SIZ<siz[e[i].y]) big[x]=e[i].y,SIZ=siz[e[i].y];
}
}
inline void dfs2(int x,int linp){
dfn[x]=++tot,Top[x]=linp;
if (!big[x]) return; dfs2(big[x],linp);
for (rr int i=as[x];i;i=e[i].next)
if (e[i].y!=big[x]&&e[i].y!=fat[x])
dfs2(e[i].y,e[i].y);
}
inline signed lca(int x,int y){
while (Top[x]^Top[y]){
if (dep[Top[x]]<dep[Top[y]]) x^=y,y^=x,x^=y;
x=fat[Top[x]];
}
if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
return x;
}
inline bool cmp(int x,int y){return dfn[x]<dfn[y];}
inline void add(int x,int y){E[++Et]=(node){y,hs[x]},W[Et]=dep[y]-dep[x],hs[x]=Et;}
inline void Insert(int x){
if (!tot) {stac[++tot]=x; return;}
rr int Lca=lca(x,stac[tot]);
while (tot>1&&dep[Lca]<dep[stac[tot-1]]) add(stac[tot-1],stac[tot]),--tot;
if (dep[Lca]<dep[stac[tot]]) add(Lca,stac[tot]),--tot;
if (stac[tot]!=Lca) stac[++tot]=Lca; stac[++tot]=x;
}
inline signed min(int a,int b){return a<b?a:b;}
inline signed max(int a,int b){return a>b?a:b;}
inline void dfs(int x){
mn[x][0]=v[x]?0:1e9,mn[x][1]=1e9,
mx[x][0]=v[x]?0:-1e9,mx[x][1]=-1e9,Siz[x]=v[x];
for (rr int i=hs[x];i;i=E[i].next){
dfs(E[i].y),Siz[x]+=Siz[E[i].y];
if (mn[x][0]>mn[E[i].y][0]+W[i])
mn[x][1]=mn[x][0],mn[x][0]=mn[E[i].y][0]+W[i];
else if (mn[x][1]>mn[E[i].y][0]+W[i])
mn[x][1]=mn[E[i].y][0]+W[i];
if (mx[x][0]<mx[E[i].y][0]+W[i])
mx[x][1]=mx[x][0],mx[x][0]=mx[E[i].y][0]+W[i];
else if (mx[x][1]>mx[E[i].y][0]+W[i])
mx[x][1]=mx[E[i].y][0]+W[i];
ans2=min(ans2,mn[x][0]+mn[x][1]);
ans3=max(ans3,mx[x][0]+mx[x][1]);
ans1+=1ll*(mm-Siz[E[i].y])*Siz[E[i].y]*W[i];
}
hs[x]=0;
}
signed main(){
n=iut();
for (rr int i=1;i<n;++i){
rr int x=iut(),y=iut();
e[++et]=(node){y,as[x]},as[x]=et;
e[++et]=(node){x,as[y]},as[y]=et;
}
dfs1(1,0),dfs2(1,1);
for (rr int Q=iut();Q;--Q){
m=iut(),mm=m,tot=Et=0,a[++m]=1;
for (rr int i=1;i<m;++i) v[a[i]=iut()]=1;
sort(a+1,a+1+m,cmp),m=unique(a+1,a+1+m)-a-1;
for (rr int i=1;i<=m;++i) Insert(a[i]);
for (;tot>1;--tot) add(stac[tot-1],stac[tot]);
ans1=0,ans2=1e9,ans3=0,dfs(1);
for (rr int i=1;i<=m;++i) v[a[i]]=0;
printf("%lld %d %d\n",ans1,ans2,ans3);
}
return 0;
}

#虚树,树形dp#洛谷 4103 [HEOI2014]大工程的更多相关文章

  1. 洛谷4103 HEOI2014大工程(虚树+dp)

    又是一道虚树好题啊 我们建出来虚树,然后考虑dp过程,我们分别令\(sum[x],mndis[x],mxdis[x],size[x]\)为子树内的路径长度和,最短链,最长链,子树内关键点个数. 对于一 ...

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

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

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

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

  4. 【BZOJ-3572】世界树 虚树 + 树形DP

    3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1084  Solved: 611[Submit][Status ...

  5. 【BZOJ-2286】消耗战 虚树 + 树形DP

    2286: [Sdoi2011消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2120  Solved: 752[Submit][Status] ...

  6. bzoj 2286(虚树+树形dp) 虚树模板

    树链求并又不会写,学了一发虚树,再也不虚啦~ 2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5002  Sol ...

  7. BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP+树剖lca

    BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的 ...

  8. BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP

    题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...

  9. [WC2018]通道——边分治+虚树+树形DP

    题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...

  10. 2018.09.25 bzoj3572: [Hnoi2014]世界树(虚树+树形dp)

    传送门 虚树入门题? 好难啊. 在学习别人的写法之后终于过了. 这道题dp方程很好想. 主要是不好写. 简要说说思路吧. 显然最优值只能够从子树和父亲转移过来. 于是我们先dfs一遍用儿子更新父亲,然 ...

随机推荐

  1. RK3568开发笔记(一):瑞芯微RK3568芯片介绍,入手开发板的核心板介绍

    前言   目前主流国产芯片为RV11XX.RK33XX.Hi35XX系列,本系列开启RK3568系列的技术教程笔记分享.  本篇主要介绍RK3568芯片和入手开发板的核心板详细介绍.   RK3568 ...

  2. linux下docker安装与初始

    1 docker的安装与使用初识 1 docker的安装 # step 1: 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persi ...

  3. select_for_update悲观锁

    例子,银行存款和撤销方法 1.用户A提取帐户 - 余额为100 $. 2.用户B提取帐户 - 余额为100 $. 3.用户B退出30 $ - 余额更新为100 $ - 30 $ = 70 $. 4.用 ...

  4. 【Azure 应用服务】更新镜像后并重启应用服务,部署日志始终没有出现加载新镜像成功的日志

    问题描述 在App Service中部署镜像文件,发现镜像一直没有部署,重启App Service服务也无效果. DockerFile如下: FROM crunchgeek/php-fpm:7.0 # ...

  5. 【Azure 应用服务】记一次 App Service 部分请求一直返回 401 "No Authority" 的情况

    问题描述 发现部署在App Service上的 WCF 应用对于所请求的接口出现部分返回 401 - No Authority 消息,10次中有一次这样的概率.比较疑惑的问题是,应用没有更新,所以怀疑 ...

  6. 通过keil内置标准库创建stm32工程

    通过keil内置标准库创建stm32工程.md body { font-family: var(--vscode-markdown-font-family, -apple-system, BlinkM ...

  7. 微信小程序测试点,9大方面全方位总结

    微信小程序无需下载安装,用户在微信扫一扫或搜索即可使用,小程序版本类型可分为:开发版.体验版.正式版. 开发版.体验版无需审核,只需要给微信号权限,经过扫小程序的二维码就能访问,正式版本需要经过微信审 ...

  8. Android Handler实现子线程与子线程、主线程之间通信

    一.子线程向主线程传值: 首选在主线程里创建一个Handler 1 Handler mHandler = new Handler(){ 2 @Override 3 public void handle ...

  9. 使用jenkins连接linux部署jar包

    jenkins安装 首先安装jenkins,我们可以使用docker安装.用下面命令拉取jenkins镜像. docker pull jenkins/jenkins 然后正常安装jenkins容器即可 ...

  10. springboot+kaptcha生成数学运算验证码和字符验证码

    使用以下代码只需要复制粘贴,修改一处文本生成器路径即可,文中有交代. 1.添加kaptcha依赖 <dependency> <groupId>com.github.penggl ...