[BZOJ1999][codevs1167][Noip2007]Core树网的核

试题描述

设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenetwork),其中V, E分别表示结点与边的集合,W表示各边长度的集合,并设T有n个结点。 路径:树网中任何两结点a,b都存在唯一的一条简单路径,用d(a,b)表示以a,b为端点的路径的长度,它是该路径上各边长度之和。我们称d(a,b)为a,b两结点间的距离。 一点v到一条路径P的距离为该点与P上的最近的结点的距离: d(v,P)=min{d(v,u),u为路径P上的结点}。 树网的直径:树网中最长的路径称为树网的直径。对于给定的树网T,直径不一定是唯一的,但可以证明:各直径的中点(不一定恰好是某个结点,可能在某条边的内部)是唯一的,我们称该点为树网的中心。 偏心距ECC(F):树网T中距路径F最远的结点到路径F的距离,即 。 任务:对于给定的树网T=(V, E,W)和非负整数s,求一个路径F,它是某直径上的一段路径(该路径两端均为树网中的结点),其长度不超过s(可以等于s),使偏心距ECC(F)最小。我们称这个路径为树网T=(V,E,W)的核(Core)。必要时,F可以退化为某个结点。一般来说,在上述定义下,核不一定只有一个,但最小偏心距是唯一的。 下面的图给出了树网的一个实例。图中,A-B与A-C是两条直径,长度均为20。点W是树网的中心,EF边的长度为5。如果指定s=11,则树网的核为路径DEFG(也可以取为路径DEF),偏心距为8。如果指定s=0(或s=1、s=2),则树网的核为结点F,偏心距为12。

输入

包含n行: 第1行,两个正整数n和s,中间用一个空格隔开。其中n为树网结点的个数,s为树网的核的长度的上界。设结点编号依次为1, 2, ..., n。 从第2行到第n行,每行给出3个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7”表示连接结点2与4的边的长度为7。 所给的数据都是正确的,不必检验。

输出

只有一个非负整数,为指定意义下的最小偏心距。

输入示例

5 2
1 2 5
2 3 2
2 4 4
2 5 3

输出示例

5

数据规模及约定

对于70%的数据,n<=200000
对于100%的数据:n<=500000, s<2^31, 所有权值<500

(原题范围:5<=n<=300, 0<=s<=1000。边长度为不超过1000 的正整数)

题解

BZOJ 太过分了,不仅数据扩大了 1K+ 倍,还卡内存。。。

随便贪心,搞出直径、直径中点,然后向两端扩展(哪头距离对应直径端点远就选择向哪头扩展,贪心)。

所有过程只需要用 BFS。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;
#define LL long longLL read() {LL x = 0, f = 1; char c = getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }return x * f;
}#define maxn 500010
#define maxm 1000010
#define maxlog 20
int n, m, far, head[maxn], next[maxm], to[maxm];
LL dist[maxm];void AddEdge(int a, int b, LL c) {to[++m] = b; dist[m] = c; next[m] = head[a]; head[a] = m;swap(a, b);to[++m] = b; dist[m] = c; next[m] = head[a]; head[a] = m;return ;
}int Q[maxn], hd, tl;
LL d[maxn];
void BFS(int s) {memset(d, -1, sizeof(d));hd = tl = 0; Q[++tl] = s;d[s] = 0;while(hd < tl) {int u = Q[++hd];for(int e = head[u]; e; e = next[e]) if(d[to[e]] < 0) {d[to[e]] = d[u] + dist[e];Q[++tl] = to[e];}}return ;
}int mid1, mid2;
LL md1, md2, td;
bool done[maxn];
void getmid(int s) {d[s] = 0; done[s] = 1;hd = tl = 0; Q[++tl] = s;while(hd < tl) {int u = Q[++hd];for(int e = head[u]; e; e = next[e]) if(!done[to[e]]) {if(d[to[e]] > d[u] + dist[e]) {d[to[e]] = d[u] + dist[e];Q[++tl] = to[e]; done[to[e]] = 1;}else if(d[to[e]] == d[u] + dist[e]) {mid1 = to[e]; md1 = d[to[e]];return ;}else {mid1 = u; mid2 = to[e];md1 = d[u]; md2 = d[to[e]];td = dist[e];return ;}}}return ;
}LL Dep[maxn];
int dep[maxn], vis[maxn], fa[maxn];
void build(int u, int pa) {fa[u] = pa;for(int e = head[u]; e; e = next[e]) if(to[e] != pa) {dep[to[e]] = dep[u] + 1;Dep[to[e]] = Dep[u] + dist[e];build(to[e], u);}return ;
}void BFS2() {memset(d, -1, sizeof(d));hd = tl = 0;for(int i = 1; i <= n; i++) if(vis[i] == 4) Q[++tl] = i, d[i] = 0;while(hd < tl) {int u = Q[++hd];for(int e = head[u]; e; e = next[e]) if(d[to[e]] < 0) {d[to[e]] = d[u] + dist[e];Q[++tl] = to[e];}}return ;
}int main() {n = read(); far = read();for(int i = 1; i < n; i++) {int a = read(), b = read(), c = read();AddEdge(a, b, c);}BFS(1);int cnt = 0, A, B;LL mx = 0;bool tp = 1;for(int i = 1; i <= n; i++) mx = max(mx, d[i]);for(int i = 1; i <= n; i++) if(mx == d[i]) cnt++, B = i;tp &= (cnt == 1);BFS(B);mx = cnt = 0;for(int i = 1; i <= n; i++) mx = max(mx, d[i]);for(int i = 1; i <= n; i++) if(mx == d[i]) cnt++, A = i;tp &= (cnt == 1);getmid(A);
//  printf("%lld %d %d %d %d %lld %lld %lld (%lld %lld)\n", mx, mid1, mid2, A, B, md1, md2, td, max(md1, md2 + td), max(md2, md1 + td));if(max(md1, md2 + td) > max(md2, md1 + td)) swap(md1, md2), swap(mid1, mid2);build(mid1, 0); vis[mid1] = 4;
//  printf("mid1: %d %lld %lld\n", mid1, Dist(mid1, A), Dist(mid2, B));int tmp = A;while(tmp != mid1) vis[tmp] = 2, tmp = fa[tmp];tmp = B;while(tmp != mid1) vis[tmp] = 3, tmp = fa[tmp];int a, b; a = b = mid1;while(far) {int ta = mid1, tb = mid1;LL da, db;for(int e = head[a]; e; e = next[e]) if(vis[to[e]] == 2) {ta = to[e], da = dist[e]; break;}for(int e = head[b]; e; e = next[e]) if(vis[to[e]] == 3) {tb = to[e], db = dist[e]; break;}if(Dep[A] - Dep[a] > Dep[B] - Dep[b]) {if(da <= far) a = ta, vis[a] = 4, far -= da;else break;}else {if(db <= far) b = tb, vis[b] = 4, far -= db;else break;}}LL ans = 0;
//  printf("%d %d %lld\n", a, b, Dist(a, b));BFS2();for(int i = 1; i <= n; i++) ans = max(ans, d[i]);printf("%lld\n", ans);return 0;
}

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6030630.html

[BZOJ1999][codevs1167][Noip2007]Core树网的核相关推荐

  1. bzoj 1999: [Noip2007]Core树网的核【树的直径+单调队列】

    我要懒死了,所以依然是lyd的课件截图 注意是min{max(max(d[uk]),dis(u1,ui),dis(uj,un))},每次都从这三个的max里取min #include<iostr ...

  2. 树网的核 Vijos1362 NOIP2007 树结构 直径 暴搜

    题面在最下方. 树结构的题做多了就会发现,本题所谓的树网的核(一段偏心距ECC最小的路径)一定是在树的直径上的. 我刚开始做的时候没想到这个,然后写了三个dfs讨论每条直径 Orz 其实只要认识到了这 ...

  3. [NOIP2007] 提高组 洛谷P1099 树网的核

    题目描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称T为树网(treebetwork),其中V,E分别表示结点与边的集合,W表示各边长度的集合,并 ...

  4. NOIP2007 树网的核 [BZOJ2282][Sdoi2011]消防

    NOIP2007 树网的核 树的直径的最长性是一个很有用的概念,可能对一些题都帮助. 树的直径 给定一棵树,树中每条边都有一个权值,树中两点之间的距离定义为连接两点的路径边权之和.树中最远的两个节点之 ...

  5. [O(N)的我不会]树网的核

    [题目描述] 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenetwork),其中V, E分别表示结点与边的集合,W表示各边长度的集 ...

  6. 树网的核(codevs 1167)

    题目描述 Description [问题描述] 设 T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我 们称T 为树网(treenetwork),其中V, E分 ...

  7. VIJOS 1362 树网的核

    描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称T为树网(treebetwork),其中V,E分别表示结点与边的集合,W表示各边长度的集合,并设T ...

  8. NOIP2007 树网的核

    传送门 最近搞一搞树型结构--毕竟自己树的知识学的太垃圾了. 首先这道题非常明显要求树的直径.树的直径有好多好多种求法,这里我选择了一位dalao的非常简洁的dfs的方法.先看一下代码. void d ...

  9. 【BZOJ1999】树网的核,求树的直径+单调队列乱搞

    传送门 思路: 很好的一道乱搞题 原来的题目我写的是O(n3)O(n^3)的 由于n<=500000 所以我们可以猜一些结论来减少时间复杂度 比如说每个直径都有最小偏心距,直径上每个点的偏心距可 ...

  10. 2017.3.21 树网的核 思考记录

    把这个noip的题搞出来了.. 不是很难,而且我的要求也比较高(虽然以前看到这种题都是直接看题解,因为太复杂不会) 虽然搞出来在luogu 的noip数据 A了,但bzoj还是T了.理论上应该是O(n ...

最新文章

  1. Unity创建使用操纵杆飞行动画教程
  2. Linux的load导入语句,LOAD DATA INFILE语句导入数据进入MySQL的一些注意事项
  3. ORACLE10g安装
  4. InstallShield 常用常量
  5. java中replaceall用法_Java中String的ReplaceAll使用小结
  6. django如何连接mysql_Django如何连接mysql
  7. Bootstrap学习之三:使用排版
  8. Ubuntu1804_server 离线安装GCC_7.5
  9. 【天光学术】美术论文:湖南传统雕刻艺术的表现形式与特点(节选)
  10. excel表格中怎样让某一行数据一直显示
  11. 三年测试经验, 字节跳动离职后, 一口气拿到 15 家公司 Offer
  12. 【Java】所有做过的面试题
  13. 查看docker里应用的版本
  14. zynq7035单板创建PYNQ镜像V2.6
  15. 最新多线程图解韩顺平老师2021
  16. 前端websockt可重连功能的插件
  17. 【问】关于火车到站的问题?
  18. 电脑开机黑屏,只有鼠标能动
  19. 疯子坐飞机,第1个人疯了,随便坐下,第n个人能够坐在自己位置上的概率
  20. Vue3(撩课学院)笔记09-axios简介,发起get请求的两种方式,发起带参的get及post请求,发起并发请求,并发请求结果将数组展开,axios全局配置,axios配置及封装,请求和响应拦截

热门文章

  1. 【Python实例第16讲】特征集聚
  2. 23种设计模式(十八)状态变化之备忘录
  3. UI设计师经常去的五个网站
  4. BZOJ3235 [Ahoi2013]好方的蛇 【单调栈 + dp】
  5. C++的四种强制转型形式:
  6. 大学毕业4年-回顾和总结(6)-技术研发-重构之法
  7. [20141124]sql server密码过期,通过SSMS修改策略报错
  8. 我的dota之路(下)
  9. docker 部署 zookeeper+kafka 集群
  10. copy 和 deepcopy的区别