【DFS好题】BZOJ1999- [Noip2007]Core树网的核(数据加强版)
NOIP的数据好水,一开始有好几个错结果NOIP数据就水过了??
【题目大意】
求无根树的直径上一段不超过S长的链,使得偏心距最小。具体概念见原题。
【思路】
首先明确几个性质:
(1)对于树中的任意一点,距离其最远的点一定是树的直径的某一端点。
(2)所有的直径是等价的,即任意一条所能求出的该最小偏心距相等。
于是我们可以用两次dfs求出直径。任取一个点找到离它最远的点r,再从r找到距离它最远的点l。l到r的路径就是直径。
显然在长度不超过S的情况下,链最长最好。在l到r上维护尽可能长的链,找到左右端点到直径做右端点的较大值的最小值。然后由链上各个点出发,找到不经过直径上的点抵达的其他点的最大深度。这个最大深度和之前的最小值中较大的就是答案。
为什么是整条直径上找最大深度,而不是在核上找呢?
显然,如果这个深度最深的点不是从核中的点,那么它到核的距离必定小于核的端点到直径端点的距离。所以如果有个节点到核的距离小于核的端点到直径端点的距离,那么它必定是从核上延伸出去的。
【错误点】
具体见程序。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=+;
const int INF=0x7fffffff;
struct edge
{
int to,len;
};
vector<edge> E[MAXN];
int n,s;
int l,r,dis[MAXN],f[MAXN],ban[MAXN]; void addedge(int u,int v,int w)
{
E[u].push_back((edge){v,w});
E[v].push_back((edge){u,w});
} void init()
{
scanf("%d%d",&n,&s);
for (int i=;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
} void dfs(int u,int fa)
{
f[u]=fa;
for (int i=;i<E[u].size();i++)
{
int to=E[u][i].to;
if (ban[to] || to==f[u]) continue;
dis[to]=dis[u]+E[u][i].len;
dfs(to,u);
}
} void getd()
{
memset(ban,,sizeof(ban)); l=,r=;
dfs(l,);
for (int i=;i<=n;i++) if (dis[i]>dis[r]) r=i; l=r;
dis[r]=;
dfs(r,);
for (int i=;i<=n;i++) if (dis[i]>dis[l]) l=i;
} void solve()
{
int i=l,j=l,ans=INF;
for (;i;i=f[i])
{
while (f[j] && dis[i]-dis[f[j]]<=s) j=f[j];
ans=min(ans,max(dis[j],dis[l]-dis[i]));
//每次找到以i为一个端点的最接近于S的链
//比较两端点和直径端点的长度
}
for (i=l;i;i=f[i]) ban[i]=;
//由于要找出不经过直径的最大深度,所以禁止访问直径上的点
for (int i=l;i;i=f[i]) dis[i]=,dfs(i,f[i]);
//★★★★★★★注意这里i的父亲必须传进去f[i],否则就修改了直径
for (int i=;i<=n;i++) ans=max(ans,dis[i]);
printf("%d",ans);
} int main()
{
init();
getd();
solve();
return ;
}
【DFS好题】BZOJ1999- [Noip2007]Core树网的核(数据加强版)的更多相关文章
- [bzoj1999][noip2007]Core树网的核
好久没写题解了.这题不算太水就写一下题解. 话说回来,虽然不水但是挺裸.可以说题意即一半题解了. 我猜粘了题面也没有人去看的,所以直接人话题意了. 给一棵树,点数1e6,(当年noip的n当然是只有3 ...
- [BZOJ1999][codevs1167][Noip2007]Core树网的核
[BZOJ1999][codevs1167][Noip2007]Core树网的核 试题描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(t ...
- BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP
BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T ...
- BZOJ1999 树网的核[数据加强版]
1999: [Noip2007]Core树网的核 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1214 Solved: 336[Submit][St ...
- 【bzoj1999】[Noip2007]Core树网的核 树的直径+双指针法+单调队列
题目描述 给出一棵树,定义一个点到一条路径的距离为这个点到这条路径上所有点的距离的最小值.求一条长度不超过s的路径,使得所有点到这条路径的距离的最大值最小. 输入 包含n行: 第1行,两个正整数n和s ...
- [BZOJ1999] 树网的核 [数据加强版] (树的直径)
传送门 如果只是想验证算法正确性这里是洛谷数据未加强版 Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenet ...
- 洛谷 1099 ( bzoj 1999 ) [Noip2007]Core树网的核
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1999 <算法竞赛进阶指南>346页.https://www.cnblogs.co ...
- [Noip2007]Core树网的核
嘟嘟嘟 首先求树的直径两次bfs即可,实际上bfs就是最短路,因为树上路径是唯一的,所以用任何一种遍历方法都行(spfa和dijkstra当然也可以). 可以证明,只要求出任意一条直径就行了,为什么呢 ...
- bzoj 1999: [Noip2007]Core树网的核【树的直径+单调队列】
我要懒死了,所以依然是lyd的课件截图 注意是min{max(max(d[uk]),dis(u1,ui),dis(uj,un))},每次都从这三个的max里取min #include<iostr ...
随机推荐
- windebug分析高cpu问题
分析高CPU的关键是找到哪个线程是持续运行,占用CPU时间. 可以隔上两分钟连续抓两个dump文件,使用 !runaway 查看线程运行的时间 通过对比两个dump文件的线程时间,看看哪个线程运行的时 ...
- Spring编程式和声明式事务实例讲解
Java面试通关手册(Java学习指南):https://github.com/Snailclimb/Java_Guide 历史回顾: 可能是最漂亮的Spring事务管理详解 Spring事务管理 S ...
- 从Python到Web开发
基础部分: 1-编程基础及Python环境部署 2-Python基础语法-内存管理-运算符-程序控制 3-Python内置结构-列表 4-Python数据类型之元组-字符串 5-python的封装与结 ...
- BigDecimal常用方法
一.介绍 Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算. 其中 BigInteg ...
- 2.SpringBoot之返回json数据
一.创建一个springBoot个项目 操作详情参考:1.SpringBoo之Helloword 快速搭建一个web项目 二.编写实体类 /** * Created by CR7 on 2017-8- ...
- 详解MySQL大表优化方案
单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的.而事实上很多时 ...
- 编写组件TComponent published $M+ 问题
报错如下: PUBLISHED caused RTTI ($M+) to be added to type 修改成下面这样之后: 解决问题 方法: 来自:http://www.cnblogs.com/ ...
- SQL CAST与CONVERT区别
CAST 和 CONVERT 将某种数据类型的表达式显式转换为另一种数据类型.CAST 和 CONVERT 提供相似的功能. 语法 使用 CAST: CAST ( expression AS data ...
- C#比较时分秒大小,终止分钟默认加十分钟,解决跨天、跨月、跨年的情况
private void cmbInHostimes_SelectedIndexChanged(object sender, EventArgs e) { DataRow[] dr; if (chkM ...
- 如何使用django+celery+RabbitMQ实现异步执行
1)安装需要安装RabbitMQ.Celery和Django-celeryCelery和Django-celery的安装直接pip就好 2)修改settings.py在INSTALLED_APPS中加 ...