bzoj 3611
和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的更多相关文章
- bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战
放波建虚树的模板. 大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于lca的都弹出去. 每次做完记得复原. 还有sort的时候一定要加cmp!!! bzoj 3611 #include&l ...
- bzoj 3611 [Heoi2014]大工程(虚树+DP)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 408 Solved: 190[Submit][Status] ...
- bzoj 3611(洛谷 4103) [Heoi2014]大工程——虚树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3611 https://www.luogu.org/problemnew/show/P4103 ...
- bzoj 3611: [Heoi2014]大工程
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...
- bzoj 3611[Heoi2014]大工程 虚树+dp
题意: 给一棵树 每次选 k 个关键点,然后在它们两两之间 新建 C(k,2)条 新通道. 求: 1.这些新通道的代价和 2.这些新通道中代价最小的是多少 3.这些新通道中代价最大的是多少 分析:较常 ...
- BZOJ.3611.[HEOI2014]大工程(虚树 树形DP)
题目链接 要求的和.最大值.最小值好像都可以通过O(n)的树形DP做,总询问点数<=2n. 于是建虚树就可以了.具体DP见DP()函数,维护三个值sum[],mx[],mn[]. sum[]要开 ...
- 大工程(bzoj 3611)
Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通 ...
- bzoj 3611: [Heoi2014]大工程 虚树
题目: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 ...
- BZOJ 3611 [Heoi2014]大工程 ——虚树
虚树第二题.... 同BZOJ2286 #include <map> #include <cmath> #include <queue> #include < ...
随机推荐
- RESTful Web 服务:教程
RESTful Web 服务:教程 随着 REST 成为大多数 Web 和 Mobile 应用的默认选择,势必要对它的基本原理有所了解. 在它提出十多年后的今天,REST 已经成为最重要的 Web ...
- lombok java代码助手
是不一个不错的代码生成工具,可以实现将代码更精简,且不失代码效率的一种不错的方法 https://www.cnblogs.com/qnight/p/8997493.html 通过java bean v ...
- [HBase]mem store flusher 流程
- Python基础(2):__doc__、文档字符串docString、help()
OS:Windows 10家庭中文版,Python:3.6.4 Python中的 文档字符串(docString) 出现在 模块.函数.类 的第一行,用于对这些程序进行说明.它在执行的时候被忽略,但会 ...
- java基础23 Math类和Random类
一.Math数学类 主要是提供很多数学的公式 1.1.Math类的常用方法 abs(int a):绝对值 ceil(double a):向上取整 floor(double a):向下取整 ...
- eclipse各种报错
1.控制台报这个错是由于tomcat的session缓存的问题; org.apache.catalina.session.StandardManager doLoad 造成原因:上次未正确关闭tomc ...
- Google Chrome中的高性能网络-[译]《转载》
以下内容是"The Performance of Open Source Applications" (POSA)的草稿, 也是The Architecture of Open S ...
- wpf image blur
RenderOptions.BitmapScalingMode="NearestNeighbor"
- linux下Ctrl命令组合
1.键盘组合键操作 ctrl-c 发送 SIGINT 信号给前台进程组中的所有进程.常用于终止正在运行的程序. ctrl-z 发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程. ...
- OpenCV持久化(二)
如何利用OpenCV持久化自己的数据结构?我们来看看OpenCV中的一个例子. MyData.hpp定义自己的数据结构MyData如下: #ifndef MYDATA_HPP #define MYDA ...