[BZOJ3611] [Heoi2014]大工程(DP + 虚树)
$dp[i][0]$表示节点i到子树中的所有点的距离之和
$dp[i][1]$表示节点i到子树中最近距离的点的距离
$dp[i][2]$表示节点i到子树中最远距离的点的距离
建好虚树后dp即可。
因为对于虚树掌握的还不是很熟,有些细节还是要注意。
虚树中可能会加入一些lca节点,这些节点在dp的时候是不应该统计的。
对于本题来说,别忘记考虑某一节点不同子树中点对的组合。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 2000010
#define LL long long using namespace std; LL ans1, ans2, dp[N][3];
int n, cnt, rp, m, top, T;
int head[N], to[N], nex[N], val[N], dis[N], size[N], dfn[N], deep[N], f[N][21], q[N], s[N], flag[N]; inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
} inline void add(int x, int y)
{
to[cnt] = y;
nex[cnt] = head[x];
head[x] = cnt++;
} inline void dfs1(int u)
{
int i, v;
dfn[u] = ++rp;
deep[u] = deep[f[u][0]] + 1;
for(i = 0; f[u][i]; i++) f[u][i + 1] = f[f[u][i]][i];
for(i = head[u]; ~i; i = nex[i])
{
v = to[i];
if(!dfn[v])
{
f[v][0] = u;
dis[v] = dis[u] + 1;
dfs1(v);
}
}
head[u] = -1;
} inline int calc_lca(int x, int y)
{
int i;
if(deep[x] < deep[y]) swap(x, y);
for(i = 20; i >= 0; i--)
if(deep[f[x][i]] >= deep[y]) x = f[x][i];
if(x == y) return x;
for(i = 20; i >= 0; i--)
if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
return f[x][0];
} inline bool cmp(int x, int y)
{
return dfn[x] < dfn[y];
} inline void dfs2(int u)
{
int i, v;
size[u] = flag[u];
dp[u][1] = 1e9, dp[u][0] = dp[u][2] = 0;
for(i = head[u]; ~i; i = nex[i])
{
v = to[i];
dfs2(v);
size[u] += size[v];
ans1 = min(ans1, dp[u][1] + dp[v][1] + dis[v] - dis[u]);
ans2 = max(ans2, dp[u][2] + dp[v][2] + dis[v] - dis[u]);
dp[u][0] += dp[v][0] + 1ll * size[v] * (m - size[v]) * (dis[v] - dis[u]);
dp[u][1] = min(dp[u][1], dis[v] - dis[u] + dp[v][1]);
dp[u][2] = max(dp[u][2], dis[v] - dis[u] + dp[v][2]);
}
if(flag[u])
{
ans1 = min(ans1, dp[u][1]);
ans2 = max(ans2, dp[u][2]);
dp[u][1] = 0;
}
head[u] = -1;
} inline void solve()
{
int i, lca;
m = read();
top = cnt = 0;
for(i = 1; i <= m; i++) q[i] = read(), flag[q[i]] = 1;
sort(q + 1, q + m + 1, cmp);
for(i = 1; i <= m; i++)
{
if(!top)
{
s[++top] = q[i];
continue;
}
lca = calc_lca(s[top], q[i]);
while(dfn[lca] < dfn[s[top]])
{
if(dfn[lca] >= dfn[s[top - 1]])
{
add(lca, s[top]);
if(s[--top] != lca) s[++top] = lca;
break;
}
add(s[top - 1], s[top]), top--;
}
s[++top] = q[i];
}
while(top > 1) add(s[top - 1], s[top]), top--;
ans2 = 0;
ans1 = 1ll * 1e9 * 1e9;
dfs2(s[1]);
printf("%lld %lld %lld\n", dp[s[1]][0], ans1, ans2);
for(i = 1; i <= m; i++) flag[q[i]] = 0;
} int main()
{
int i, x, y;
n = read();
memset(head, -1, sizeof(head));
for(i = 1; i < n; i++)
{
x = read();
y = read();
add(x, y);
add(y, x);
}
dfs1(1);
T = read();
while(T--) solve();
return 0;
}
[BZOJ3611] [Heoi2014]大工程(DP + 虚树)的更多相关文章
- [Bzoj3611][Heoi2014]大工程(虚树)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 2000 Solved: 837[Submit][Status ...
- BZOJ3611 [Heoi2014]大工程 【虚树】
题目 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a ...
- 【BZOJ3611】大工程(虚树,动态规划)
[BZOJ3611]大工程(虚树,动态规划) 题面 BZOJ Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树 ...
- [BZOJ3611][Heoi2014]大工程(虚树上DP)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 2464 Solved: 1104[Submit][Statu ...
- bzoj 3611 [Heoi2014]大工程(虚树+DP)
3611: [Heoi2014]大工程 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 408 Solved: 190[Submit][Status] ...
- 【BZOJ3611】大工程(虚树,DFS序,树形DP)
题意:有一棵树,树有边权,有若干次询问,给出一些点,求: 1.这些点互相之间的距离之和 2.点对距离中的最大和最小值 n<=1000000 q<=50000并且保证所有k之和<=2* ...
- 洛谷4103 HEOI2014大工程(虚树+dp)
又是一道虚树好题啊 我们建出来虚树,然后考虑dp过程,我们分别令\(sum[x],mndis[x],mxdis[x],size[x]\)为子树内的路径长度和,最短链,最长链,子树内关键点个数. 对于一 ...
- [BZOJ3611][Heoi2014]大工程
[BZOJ3611][Heoi2014]大工程 试题描述 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 ...
- BZOJ2286 [Sdoi2011]消耗战 和 BZOJ3611 [Heoi2014]大工程
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6371 Solved: 2496[Submit][Statu ...
- BZOJ3611:[HEOI2014]大工程(树形DP,虚树)
Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上. 在 2 个国家 a,b 之间建一条新通 ...
随机推荐
- 【Web应用-迁移】迁移 Web 应用到新的应用服务计划的相关限制和说明
现象描述 当前 Web 应用所在的应用服务计划和目标应用服务计划属于同一个资源组,但是通过 Portal 点击 “更改应用服务计划”,依旧看不到目标应用服务计划. 问题分析 导致上述问题的原因是,用户 ...
- EJB配置jboss数据源
1.数据源的模板在\jboss-4.2.3.GA-jdk6\jboss-4.2.3.GA\docs\examples\jca\下2.编辑数据源文件,比如mysql-ds.xml,命名规则是名称-ds. ...
- LINUX 安装JDK (rpm格式和tar.gz格式)
谷歌博客地址:http://tsaiquinn.blogspot.com/2014/10/linux-jdk-rpmtargz.html JDK rpm方式: 我使用的是SecureCRT,先下载了然 ...
- 第八篇:cx_Oracle出现的问题
1.cx_Oracle.DatabaseError: ORA-24315: illegal attribute type 2.cx_Oracle.InterfaceError: Unable to a ...
- Asp.Net Core 进阶(三)—— IServiceCollection依赖注入容器和使用Autofac替换它
Asp.Net Core 提供了默认的依赖注入容器 IServiceCollection,它是一个轻量级的依赖注入容器,所以功能不多,只是提供了基础的一些功能,要实现AOP就有点麻烦,因此在实际工作当 ...
- 量化投资,你需要了解的A股财务数据
摘要:基本面量化是应用量化研究领域的重头戏,财务数据的整理和加工是基本面量化的第一步.本文梳理了财务数据的基本知识,包括报表类型.数据来源.调整更正和使用原则等,并给出了单季度和TTM数据的计算流程. ...
- WINDOWS-API:API函数大全
操作系统除了协调应用程序的执行.内存分配.系统资源管理外,同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务是一个函数),可以帮肋应用程序达到开启视窗.描绘图形.使用周边设备的目的,由 ...
- 还有这种书,程序开发心理学(豆瓣) - 豆瓣读书,转载自:https://book.douban.com/subject/1141154/
登录/注册 下载豆瓣客户端 豆瓣 读书 电影 音乐 同城 小组 阅读 FM 时间 豆品 更多 豆瓣读书 购书单 电子图书 豆瓣书店 2018年度榜单 2018书影音报告 购物车 程序开发心理学 作 ...
- CSS3-文本-text-overflow
text-overflow 语法: text-overflow : clip | ellipsis 取值说明: 1.clip:表示不显示省略标记(...),而只是简单的裁切,需要在一定的高度范围内配合 ...
- 【php】运算符优先级界定
<?php $i = 1; $array[$i] = $i++; print_r($array);die; //输出 Array([2] => 1) $a = 1; echo $a + $ ...