#虚树,树形dp#洛谷 4103 [HEOI2014]大工程
分析
建一棵虚树,然后树形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]大工程的更多相关文章
- 洛谷4103 HEOI2014大工程(虚树+dp)
又是一道虚树好题啊 我们建出来虚树,然后考虑dp过程,我们分别令\(sum[x],mndis[x],mxdis[x],size[x]\)为子树内的路径长度和,最短链,最长链,子树内关键点个数. 对于一 ...
- bzoj 3611(洛谷 4103) [Heoi2014]大工程——虚树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3611 https://www.luogu.org/problemnew/show/P4103 ...
- 洛谷P4103 [HEOI2014]大工程(虚树 树形dp)
题意 链接 Sol 虚树. 首先建出虚树,然后直接树形dp就行了. 最大最小值直接维护子树内到该节点的最大值,然后合并两棵子树的时候更新一下答案. 任意两点的路径和可以考虑每条边两边的贡献,\(d[x ...
- 【BZOJ-3572】世界树 虚树 + 树形DP
3572: [Hnoi2014]世界树 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1084 Solved: 611[Submit][Status ...
- 【BZOJ-2286】消耗战 虚树 + 树形DP
2286: [Sdoi2011消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2120 Solved: 752[Submit][Status] ...
- bzoj 2286(虚树+树形dp) 虚树模板
树链求并又不会写,学了一发虚树,再也不虚啦~ 2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5002 Sol ...
- BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP+树剖lca
BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的 ...
- BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP
题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...
- [WC2018]通道——边分治+虚树+树形DP
题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...
- 2018.09.25 bzoj3572: [Hnoi2014]世界树(虚树+树形dp)
传送门 虚树入门题? 好难啊. 在学习别人的写法之后终于过了. 这道题dp方程很好想. 主要是不好写. 简要说说思路吧. 显然最优值只能够从子树和父亲转移过来. 于是我们先dfs一遍用儿子更新父亲,然 ...
随机推荐
- 最简单的python判断是否是回文
def isNumberPalindrome(number): if isinstance(number, int): number = str(number) return number == nu ...
- 【C++ OOP 01】封装
封装 封装的意义 封装是C++面向对象三大特性之一 封装的意义: 将属性和行为作为一个整体,表现生活中的事物 将属性和行为加以权限控制 封装意义一 在设计类的时候,属性和行为写在一起,表现事物 语 ...
- [软件工程] CMMI是什么?
序 能力成熟度模型集成(CMMI) 一.CMMI(能力成熟度模型集成)概述 CMMI是由美国软件工程学会(software engineering institue,简称SEI)制定的一套专门针对软件 ...
- zynq7000 I2C RTC 与 串口使用
RS485 串口 测试 硬件上2路串口,其中UART 1对应PS STD IN/OUT,UART 0对应RS485: 图 ‑1 RS485电路,自动转换输入.输出方向 可参考 https://blog ...
- 图数据库 Nebula Graph 的代码变更测试覆盖率实践
对于一个持续开发的大型工程而言,足够的测试是保证软件行为符合预期的有效手段,而不是仅仅依靠 code review 或者开发者自己的技术素质.测试的编写理想情况下应该完全定义软件的行为,但是通常情况都 ...
- java获取kafka consumer lag、endOffsets、beginningOffsets以及 KafkaConsumer总结
一.java获取kafka consumer lag.endOffsets.beginningOffsets maven依赖: <dependency> <groupId>or ...
- [程序] C++实现 http和https的反向代理程序
目录 前言 代理原理 http代理 https代理 实现 客户端 服务端 遇到的所有问题记录 Python对于回复不响应 接受的数据只有4字节 最终数据已经发给Python了 但是Python还是阻塞 ...
- Java 常用类 String的常用方法(1)
1 package com.bytezero.stringclass; 2 3 import org.junit.Test; 4 5 import java.sql.SQLOutput; 6 impo ...
- XAF Number(编号)
前言 编号在各类系统中都会存在,同时它还会根据业务场景的不同,会有不同的生成规则.XAF提供了一个编号生成助手(DistributedIdGeneratorHelper),它能在多并发的情况下,生成一 ...
- Spring整合mybatis使用xml配置事务
自己准备开始教授Java相关的技术,Spring框架是必须让学生学习的框架之一.里面有一个事务相关的 配置,以前刚学习Spring框架的时候有接触过,只是过了很多年,很多东西都已经淡忘.再来回忆一下 ...