和BZOJ消耗站一样,先将那个询问的简图构建出来,然后就是简单的树形DP。

(倍增数组开小了,然后就狂WA,自己生成的极限数据深度又没有那么高,链又奇迹般正确)

 #include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define oo 0x3f3f3f3f3f3f3f3f
#define N 1000010
#define P 19
using namespace std; typedef long long dnt; int n, m;
vector<int> g[N];
int dfn[N], anc[N][P+], dep[N], idc;
int head[N], ikey[N], dest[N+N], next[N+N], etot;
dnt dp[N][];
int qcnt, aa[N], stk[N], top;
dnt ans[]; void adde( int u, int v ) {
etot++;
next[etot] = head[u];
dest[etot] = v;
head[u] = etot;
}
void dfs( int u ) {
dfn[u] = ++idc;
for( int p=; p<=P; p++ )
anc[u][p] = anc[anc[u][p-]][p-];
for( int t=; t<g[u].size(); t++ ) {
int v=g[u][t];
if( v==anc[u][] ) continue;
anc[v][] = u;
dep[v] = dep[u]+;
dfs(v);
}
}
bool cmp( int u, int v ) {
return dfn[u]<dfn[v];
}
int lca( int u, int v ) {
if( dep[u]<dep[v] ) swap(u,v);
int t=dep[u]-dep[v];
for( int p=; t; t>>=,p++ )
if( t& ) u=anc[u][p];
if( u==v ) return u;
for( int p=P; p>= && anc[u][]!=anc[v][]; p-- )
if( anc[u][p]!=anc[v][p] ) u=anc[u][p], v=anc[v][p];
return anc[u][];
}
void build() {
stk[top=] = ;
head[] = ; sort( aa+, aa++qcnt, cmp ); etot = ;
for( int i=-(aa[]!=); i<=qcnt; i++ ) {
int ca=lca(aa[i],stk[top]);
while( dep[ca]<dep[stk[top]] ) {
int u;
u = stk[top--];
if( dep[ca]>=dep[stk[top]] ) {
if( ca!=stk[top] ) {
stk[++top] = ca;
head[ca] = ;
}
adde( stk[top], u );
break;
}
adde( stk[top], u );
}
stk[++top] = aa[i];
head[aa[i]] = ;
}
for( int i=top; i>=; i-- )
adde( stk[i-], stk[i] );
}
dnt sml, big, sum, cnt;
void dodp( int u ) {
if( ikey[u] ) {
dp[u][] = ;
dp[u][] = ;
dp[u][] = ;
dp[u][] = ;
} else {
dp[u][] = oo;
dp[u][] = -oo;
dp[u][] = ;
dp[u][] = ;
}
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
dnt w=dep[v]-dep[u];
dodp(v);
dp[u][] = min( dp[u][], dp[v][]+w );
dp[u][] = max( dp[u][], dp[v][]+w );
dp[u][] += dp[v][];
dp[u][] += dp[v][]+w*dp[v][];
}
if( ikey[u] ) {
sml = ;
big = ;
sum = ;
cnt = ;
} else {
sml = oo;
big = -oo;
sum = ;
cnt = ;
}
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
dnt w=dep[v]-dep[u];
ans[] = min( ans[], sml+w+dp[v][] );
ans[] = max( ans[], big+w+dp[v][] );
ans[] += cnt*(dp[v][]+w*dp[v][]) + sum*dp[v][];
sml = min( sml, dp[v][]+w );
big = max( big, dp[v][]+w );
cnt += dp[v][];
sum += dp[v][]+w*dp[v][];
}
}
int main() {
scanf( "%d", &n );
for( int i=,u,v; i<n; i++ ) {
scanf( "%d%d", &u, &v );
g[u].push_back( v );
g[v].push_back( u );
}
anc[][] = ;
dep[] = ;
dfs();
scanf( "%d", &m );
for( int i=; i<=m; i++ ) {
scanf( "%d", &qcnt );
for( int j=; j<=qcnt; j++ )
scanf( "%d", aa+j ); if( qcnt== ) {
printf( "0 0 0\n" );
continue;
} build(); for( int j=; j<=qcnt; j++ )
ikey[aa[j]] = ;
ans[] = oo;
ans[] = ;
ans[] = ;
dodp();
for( int j=; j<=qcnt; j++ )
ikey[aa[j]] = ; printf( "%lld %lld %lld\n", ans[], ans[], ans[] );
}
}

bzoj 3611的更多相关文章

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

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

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

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

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

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

  4. bzoj 3611: [Heoi2014]大工程

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

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

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

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

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

  7. 大工程(bzoj 3611)

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

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

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

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

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

随机推荐

  1. 【技巧总结】Penetration Test Engineer[1]-Basic

    1.渗透测试基础 1.1.渗透测试分类 黑盒测试:从远程网络位置来评估目标网络基础设施,没有任何相关信息 白盒测试:内部发起,了解到关于目标环境的所有内部与底层知识 灰盒测试:结合两者优势,根据对目标 ...

  2. XXX变种-防火墙放行自身

    1.利用防火墙命令放行自身手法 netsh firewall add allowedprogram "C:\Users\USER\AppData\Local\Temp\Discord Can ...

  3. Linux的bg和fg命令 ---让程序在前台后台之间切换

    Linux的bg和fg命令 我们都知道,在 Windows 上面,我们要么让一个程序作为服务在后台一直运行,要么停止这个服务.而不能让程序在前台后台之间切换.而 Linux 提供了 fg 和 bg 命 ...

  4. 电脑蓝屏提示unexpected store exception的解决方法

    在我们使用电脑的过程中常常会遇到许多问题,对于许多不熟悉电脑的用户常常摸不着头脑,而部分用户在使用电脑时,电脑常常出现蓝屏的情况,并提示你的电脑遇到问题需要重新启动,与此同时,其报告错误代码为“une ...

  5. mac 删除垃圾篓中的文件

    1.打开终端输入: sudo rm -rf /Volumes/kaid/.Trashes/ 2.输入本机密码

  6. 如何阻止点击scrollviewer里面的单位内容时,自动滚动

    <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="FocusVisualStyle ...

  7. java 内部类可以被覆盖吗

    如果创建了一个内部类,然后继承其外围类并重新定义内部类时,"覆盖"内部类就好像是其外围类的一个方法,并不起作用, 这两个内部类是完全独立的两个实体,各自在自己的命名空间内 //: ...

  8. java 内部类与控制框架

    应用程序控制框架(application framework)就是设计解决某类特殊问题的一个类,或一组类,要运用某个应用程序框架,通常是继承一个类或多个类,并覆盖这些方法.在覆盖的方法中编写代码定制应 ...

  9. 不同意义的new和delete

    补充说明: new/delete是运算符而非函数,operator new/delete并非是new/delete的重载.事实上,我们无法自定义new/delete的行为: operator new/ ...

  10. Centos之字符串搜索命令grep

    grep [选项] 字符串 文件名 在文件当中匹配符合条件的字符串 选项: -i 忽略大小写 -v 排除指定字符串 [root@localhost ~]# grep "work" ...