虚树第二题。。。。

同BZOJ2286

#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define mp make_pair
#define inf 0x3f3f3f3f
#define maxn 2000005
int h[maxn],to[maxn],ne[maxn],en=0;
int n,dep[maxn],st[maxn][22],in[maxn],out[maxn],ord[maxn],tot;
int _log[maxn],m,sta[maxn],top=0,se[maxn],idx,k,a[maxn]; void add(int a,int b)
{to[en]=b;ne[en]=h[a];h[a]=en++;} void dfs1(int o,int fa)
{
in[o]=++tot;ord[tot]=o;
for (int i=h[o];i>=0;i=ne[i])
if (to[i]!=fa)
{
dep[to[i]]=dep[o]+1;
dfs1(to[i],o);
ord[++tot]=o;
}
out[o]=tot;
} void initst()
{
F(i,2,maxn-1) _log[i]=_log[i>>1]+1;
F(i,1,21) F(j,1,tot-(1<<i)+1)
{
if (dep[st[j][i-1]]<dep[st[j+(1<<i-1)][i-1]]) st[j][i]=st[j][i-1];
else st[j][i]=st[j+(1<<i-1)][i-1];
}
} int lca(int l,int r)
{
l=in[l];r=in[r];if (l==r) return st[l][0];
if (l>r) swap(l,r);int tmp=_log[r-l+1];
if (dep[st[l][tmp]]<dep[st[r-(1<<tmp)+1][tmp]]) return st[l][tmp];
else return st[r-(1<<tmp)+1][tmp];
} void debug()
{
int a,b;
while (scanf("%d%d",&a,&b)!=EOF)
printf("%d\n",lca(a,b));
} bool cmp(int a,int b)
{
return in[a]<in[b];
} int hd[maxn],tl[maxn],nxt[maxn],ed,lst[maxn]; void add_edge(int a,int b)
{
if (lst[a]!=idx) lst[a]=idx,hd[a]=-1;
tl[ed]=b;
nxt[ed]=hd[a];
hd[a]=ed++;
} int siz[maxn],mn[maxn],mx[maxn],ans_max,ans_min; ll dfs2(int o,int fa)
{
siz[o]=0;ll ret=0;
mn[o]=inf;mx[o]=-inf;
if (se[o]==idx) mn[o]=0,mx[o]=0,siz[o]++;
for (int i=hd[o];i>=0;i=nxt[i])
if (tl[i]!=fa){
ret+=dfs2(tl[i],o);
siz[o]+=siz[tl[i]];
ans_max=max(ans_max,mx[o]+mx[tl[i]]+dep[tl[i]]-dep[o]);
ans_min=min(ans_min,mn[o]+mn[tl[i]]+dep[tl[i]]-dep[o]);
mn[o]=min(mn[o],mn[tl[i]]+dep[tl[i]]-dep[o]);
mx[o]=max(mx[o],mx[tl[i]]+dep[tl[i]]-dep[o]);
}
for (int i=hd[o];i>=0;i=nxt[i])
if (tl[i]!=fa){
ret+=((ll)k-(ll)siz[tl[i]])*(ll)siz[tl[i]]*((ll)dep[tl[i]]-(ll)dep[o]);
}
return ret;
} int main()
{
memset(h,-1,sizeof h);
scanf("%d",&n);
F(i,2,n)
{
int a,b;scanf("%d%d",&a,&b);
add(a,b);add(b,a);
}
dfs1(1,-1);
F(i,1,tot) st[i][0]=ord[i]; initst();
scanf("%d",&m);
for (idx=1;idx<=m;++idx)
{
ed=0;
scanf("%d",&k);
F(i,1,k) scanf("%d",&a[i]);
sort(a+1,a+k+1,cmp);
int rt=a[1];F(i,2,k) rt=lca(rt,a[i]);
sta[top=1]=rt;
F(i,1,k)
{
se[a[i]]=idx; if (a[i]==rt) continue;
int x=lca(a[i],sta[top]); //printf("Add and lca is %d\n",x);
while(dep[x]<dep[sta[top]])
{
int tmp;
if (dep[x]>dep[sta[top-1]])tmp=x;
else tmp=sta[top-1];
add_edge(sta[top],tmp);
add_edge(tmp,sta[top]);
top--;
}
if (x!=sta[top]) sta[++top]=x;
sta[++top]=a[i];
}
while (top>1) add_edge(sta[top],sta[top-1]),add_edge(sta[top-1],sta[top]),top--;
ans_max=-inf;ans_min=inf;
printf("%lld",dfs2(rt,0));
printf(" %d %d\n",ans_min,ans_max);
}
}

  

BZOJ 3611 [Heoi2014]大工程 ——虚树的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战

    放波建虚树的模板. 大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于lca的都弹出去. 每次做完记得复原. 还有sort的时候一定要加cmp!!! bzoj 3611 #include&l ...

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

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

  8. bzoj 3611: [Heoi2014]大工程

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

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

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

随机推荐

  1. IOS7适配

    (1)如果应用程序始终隐藏 status bar 那么恭喜呢,你在UI上需要的改动很少很少. (2)如果应用程序显示status bar,可以讲status bar设置成黑色不透明 ,然后在UIVie ...

  2. Java之instanceof

    class Base{     int x = 1;     static int y = 2;     String name(){         return "mother" ...

  3. POJ Washing Clothes 洗衣服 (01背包,微变型)

    题意:有多种颜色的衣服,由两个人合作来洗,必须洗完一种颜色才能洗下一种,求需要多少时间能洗完. 思路:将衣服按颜色分类,对每种颜色进行01背包,容量上限是该种颜色衣服全部洗完的耗时长一半,其实就是在最 ...

  4. 【单片机实验】6LED静态串行显示

    实验三 6LED静态串行显示一.实验目的1.掌握数字.字符转换成由数码管显示的八段码的软件译码方法及译码过程:2.静态显示的原理和相关程序的编写. 二.实验电路静态显示 电路如图3-2所示.显示器由6 ...

  5. LeetCode || 双指针 / 单调栈

    11. Container With Most Water 题意:取两根求最大体积 思路:使用两个指针分别指向头和尾,然后考虑左右两根: 对于小的那根,如果选择了它,那么能够产生的最大体积一定是当前的 ...

  6. Java习题附答案

    第一章练习题(Java入门) 1.下列哪项不是JDK所包含的内容?(选一项)C 红色代表正确答案 A.Java编程语言 B.工具及工具的API C.Java EE扩展API D.Java平台虚拟机 2 ...

  7. Sniper OJ部分writeup

    0x00 shellcode pwn 因为题目直接有源码,我就不拖进IDA了,直接看代码 这是一个典型的栈溢出,我们只需要构造shellcode获得/bin/sh权限就可以得到flag.下面是所用脚本 ...

  8. Luogu P4231 三步必杀 (差分)

    目录 题目 题解 题目 题目链接 题目背景 (三)旧都 离开狭窄的洞穴,眼前豁然开朗. 天空飘着不寻常的雪花. 一反之前的幽闭,现在面对的,是繁华的街市,可以听见酒碗碰撞的声音. 这是由被人们厌恶的鬼 ...

  9. MySQL 之视图、 触发器、事务、存储过程、内置函数、流程控制、索引

    本文内容: 视图 触发器 事务 存储过程 内置函数 流程控制 索引 ------------------------------------------------------------------ ...

  10. python--基础数据类型的补充与深浅copy

    一 . join的用法 lst =['吴彦祖','谢霆锋','刘德华'] s = '_'.join(lst) print(s) # 吴彦祖_谢霆锋_刘德华 # join() "*" ...