BZOJ4890 [Tjoi2017]城市 【树形dp】
题目链接
题解
枚举断开哪一条边,然后对剩余的两棵树分别做一遍换根法树形dp
需要求出每个点到树中其它点距离的最大值\(f[i]\)和次大值\(g[i]\)【用以辅助换根计算最大值】
求出每棵树中的最长路径,然后再将两棵树中\(f[i]\)最小值相连保证相连后产生的最大值最小
\(O(n^2)\)的复杂度
如果怕被卡常,可以知道要切的边一定在直径上,虽然上界没有变,但速度可以快不少
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 5005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int h[maxn],ne = 1;
struct EDGE{int from,to,nxt,w,flag;}ed[maxn << 1];
inline void build(int u,int v,int w){
ed[++ne] = (EDGE){u,v,h[u],w,1}; h[u] = ne;
ed[++ne] = (EDGE){v,u,h[v],w,1}; h[v] = ne;
}
int f[maxn],g[maxn],ch[maxn],d[maxn],du,path[maxn],fa[maxn];
int n,ans,fans,mnans;
void DFS(int u,int Fa){
if (d[u] > d[du]) du = u;
Redge(u) if ((to = ed[k].to) != Fa){
d[to] = d[u] + ed[k].w; path[to] = k;
DFS(to,u);
}
}
void dfs(int u){
f[u] = g[u] = 0;
Redge(u) if (ed[k].flag && (to = ed[k].to) != fa[u]){
fa[to] = u; d[to] = ed[k].w; dfs(to);
if (f[to] + ed[k].w > f[u]){
g[u] = f[u];
f[u] = f[to] + ed[k].w;
ch[u] = to;
}
else if (f[to] + ed[k].w > g[u]) g[u] = f[to] + ed[k].w;
}
fans = max(fans,f[u]);
}
void dfs2(int u){
if (fa[u]){
int v = fa[u];
if (ch[v] == u){
if (g[v] + d[u] > f[u]){
g[u] = f[u];
f[u] = g[v] + d[u];
ch[u] = v;
}
else if (g[v] + d[u] > g[u]) g[u] = g[v] + d[u];
}
else {
if (f[v] + d[u] > f[u]){
g[u] = f[u];
f[u] = f[v] + d[u];
ch[u] = v;
}
else if (f[v] + d[u] > g[u]) g[u] = f[v] + d[u];
}
}
Redge(u) if (ed[k].flag && (to = ed[k].to) != fa[u]){
dfs2(to);
}
fans = max(fans,f[u]);
mnans = min(mnans,f[u]);
}
int dp(int rt){
d[rt] = 0; fa[rt] = 0; dfs(rt);
mnans = INF;
dfs2(rt);
return mnans;
}
int main(){
n = read(); int a,b,w; ans = INF;
for (int i = 1; i < n; i++){
a = read(); b = read(); w = read();
build(a,b,w);
}
d[du = 1] = 0; DFS(1,0);
path[du] = 0; d[du] = 0; DFS(du,0);
int t1,t2;
for (int i = du; path[i]; i = ed[path[i]].from){
int k = path[i];
ed[k].flag = ed[k ^ 1].flag = false;
cls(f); cls(g); fans = 0;
t1 = dp(ed[k].from);
t2 = dp(ed[k].to);
//REP(j,n) printf("%d ",f[j]); puts("");
fans = max(fans,t1 + t2 + ed[k].w);
//printf("(%d,%d) mx = %d\n",ed[k].to,ed[k].from,fans);
ans = min(ans,fans);
ed[k].flag = ed[k ^ 1].flag = true;
}
printf("%d\n",ans);
return 0;
}
BZOJ4890 [Tjoi2017]城市 【树形dp】的更多相关文章
- BZOJ 4890: [Tjoi2017]城市 树形dp
标签:树形dp,枚举,树的直径 一上来看到这个题就慌了,只想到了 $O(n^3)$ 的做法. 碰到这种题时要一步一步冷静地去分析,观察数据范围. 首先,$n\leqslant 5000$,所以可以先 ...
- bzoj4890[Tjoi2017]城市(树的半径)
4890: [Tjoi2017]城市 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 149 Solved: 91[Submit][Status][D ...
- [BZOJ4890][TJOI2017]城市(DP)
题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公路相互可达,但是通过一条高速公路需要收 ...
- BZOJ4890 Tjoi2017城市
显然删掉的边肯定是直径上的边.考虑枚举删哪一条.然后考虑怎么连.显然新边应该满足其两端点在各自树中作为根能使树深度最小.只要线性求出这个东西就可以了,这与求树的重心的过程类似. #include< ...
- 树形dp专题总结
树形dp专题总结 大力dp的练习与晋升 原题均可以在网址上找到 技巧总结 1.换根大法 2.状态定义应只考虑考虑影响的关系 3.数据结构与dp的合理结合(T11) 4.抽直径解决求最长链的许多类问题( ...
- 【BZOJ4890】[TJOI2017]城市(动态规划)
[BZOJ4890][TJOI2017]城市(动态规划) 题面 BZOJ 洛谷 题解 数据范围都这样了,显然可以暴力枚举断开哪条边. 然后求出两侧直径,暴力在直径上面找到一个点,使得其距离直径两端点的 ...
- 洛谷 P1453 城市环路 ( 基环树树形dp )
题目链接 题目背景 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域--城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市 ...
- 换根DP+树的直径【洛谷P3761】 [TJOI2017]城市
P3761 [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公 ...
- 【牛客】乃爱与城市拥挤程度 — 树形dp,up and down
我太难了 这题做得我要死了,来来回回写了大概八九个小时 错误的原因要么是快速幂写错(一生之敌,要么是忘取模爆\(longlong\)变负数\(QAQ\) \(update\) \(2019.11.13 ...
随机推荐
- SSI框架下,用jxl实现导出功能
SSI框架下,用jxl实现导出功能 先说明一下,这个是SSI框架下,前端用ExtJs,应用在一个企业级的系统中的导出功能,因为是摸索着做的,所以里面有一些代码想整理一下,如果有人看到了,请视自己的架构 ...
- opendaylight安装
OpenDaylight安装 环境 jdk-1.8 maven 环境配置安装 Java环境 查看Java环境 java -version 安装jdk-1.8 yum install java-1.8 ...
- 【转载】最长回文字符串(manacher算法)
原文转载自:http://blog.csdn.net/lsjseu/article/details/9990539 偶然看见了人家的博客发现这么一个问题,研究了一下午, 才发现其中的奥妙.Stupid ...
- 使用CSS隐藏HTML元素的四种常用方法
CSS隐藏HTML元素的四种常用方法 1.opacity:设置opacity: 0可以使一个元素变得完全透明. 设置的透明度会被子元素继承,而且无法取消. 通常可以使用opacity属性来制作元素的淡 ...
- MPP(大规模并行处理)
1. 什么是MPP? MPP (Massively Parallel Processing),即大规模并行处理,在数据库非共享集群中,每个节点都有独立的磁盘存储系统和内存系统,业务数据根据数据库模型和 ...
- 图解HTTP总结(1)——了解Web及网络基础
Web页面不能凭空显示出来.根据Web浏览器地址栏指定的URL,Web浏览器从Web服务器端获取文件资源等信息,从而显示出Web页面. Web使用一种名为HTTP(HyperText Transfe ...
- python系列3之内置函数和文件操作
目录 自定义函数 内置函数 文件的操作 练习题 一. 自定义函数 1. 函数的创建 函数的创建 1.def关键字 2.函数名+() 3.冒号 4.缩进 5. return返回值,可以不写,默认的返回值 ...
- PTA 7-10(图) 旅游规划 最短路问题
7-10(图) 旅游规划 (25 分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果 ...
- Android stadio 自定义debug release keystore
1.添加siggnig name 随意,不过按我写的就可以了.设置完成之后,你的build.grade就会多出来一些: android { signingConfigs { signingConfig ...
- HEXO next live2d插件删除问题
title: HEXO next live2d插件删除问题 date: 2018-03-06 13:09:12 updated: tags: [hexo,next,建站,学习,前端技术,疑问] des ...