传送门

$ \color{green} {solution : }$

我们可以暴力枚举断边,然后 $ O(n) $ 的跑一次换根 $ dp $,然后复杂度是 $ O(n * n) $ 的

#include <bits/stdc++.h>
using namespace std;

const int maxn = 100010;

template <typename T> inline void G(T &x) {
    x = 0; char o; bool f = false;
    for ( ; !isdigit(o = getchar()); ) {
        if( o == '-') {
            f = true;
        }
    }
    for ( ; isdigit(o); o = getchar()) {
        x = (x << 1) + (x << 3) + (o & 15);
    }
    if( f) {
        x = ~x + 1;
    }
}

template <typename T> inline bool check_Max(T &x, const T &y) {
    return x < y ? x = y, false : true;
}

template <typename T> inline bool check_Min(T &x, const T &y) {
    return x > y ? x = y, false : true;
}

struct Edge {
    int v, w; Edge *to;
    Edge ( int v, int w, Edge *to) : v(v), w(w), to(to) {}
    Edge () {}
}*head[maxn], pool[maxn<<1], *pis = pool;

int di[maxn], ndi[maxn];

inline void dfs1(int u, int pre, int &Mx) {
    di[u] = ndi[u] = 0;
    for ( Edge *now = head[u]; now; now = now->to) if( now->v ^ pre) {
        dfs1(now->v, u, Mx);
        check_Max(ndi[u], di[now->v] + now->w);
        if(ndi[u] > di[u]) {
            swap(ndi[u], di[u]);
        }
    }
    check_Max(Mx, ndi[u] + di[u]);
}

inline void dfs2(int u, int pre, int &Mx) {
    check_Min(Mx, di[u]);
    for ( Edge *now = head[u]; now; now = now->to) if( now->v ^ pre) {
        if( di[u] == di[now->v] + now->w) {
            check_Max(ndi[now->v], ndi[u] + now->w);
        }
        else {
            check_Max(ndi[now->v], di[u] + now->w);
        }
        if( ndi[now->v] > di[now->v]) {
            swap(di[now->v], ndi[now->v]);
        }
        dfs2(now->v, u, Mx);
    }
}

int n;

struct line {
    int l, r, w;
}data[maxn];

int main() {
    G(n);
    for ( register int i = 1; i < n; ++ i) {
        G(data[i].l); G(data[i].r); G(data[i].w);
        int u = data[i].l, v = data[i].r, w = data[i].w;
        head[u] = new (pis ++) Edge(v, w, head[u]); head[v] = new (pis ++) Edge(u, w, head[v]);
    }
    int ans = 0x7fffffff;
    for ( register int i = 1; i < n; ++ i) {
        int mx1 = 0, mx2 = 0, ret = 0;
        dfs1(data[i].l, data[i].r, mx1); dfs1(data[i].r, data[i].l, mx2);
        check_Max(ret, mx1); check_Max(ret, mx2);
        int mx3 = di[data[i].l], mx4 = di[data[i].r];
        dfs2(data[i].l, data[i].r, mx3); dfs2(data[i].r, data[i].l, mx4);
        check_Max(ret, mx3 + mx4 + data[i].w);
        check_Min(ans, ret);
    }
    printf("%d\n",ans);
    return 0;
}

[BZOJ 4890][TJOI2017]城市的更多相关文章

  1. BZOJ 4890: [Tjoi2017]城市 树形dp

    标签:树形dp,枚举,树的直径 一上来看到这个题就慌了,只想到了 $O(n^3)$ 的做法. 碰到这种题时要一步一步冷静地去分析,观察数据范围. 首先,$n\leqslant 5000$,所以可以先 ...

  2. bzoj4890[Tjoi2017]城市(树的半径)

    4890: [Tjoi2017]城市 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 149  Solved: 91[Submit][Status][D ...

  3. 【BZOJ4890】[TJOI2017]城市(动态规划)

    [BZOJ4890][TJOI2017]城市(动态规划) 题面 BZOJ 洛谷 题解 数据范围都这样了,显然可以暴力枚举断开哪条边. 然后求出两侧直径,暴力在直径上面找到一个点,使得其距离直径两端点的 ...

  4. [洛谷P3761] [TJOI2017]城市

    洛谷题目链接:[TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速 ...

  5. Luogu 3761 [TJOI2017]城市

    BZOJ 4890. 在树上断开一条边之后会形成两个联通块,如果要使这一条边接回去之后保持一棵树的形态,那么必须在两个联通块之间各找一个点连接. 那么,对于每一条可能断开的边,它产生的答案是以下两者的 ...

  6. 换根DP+树的直径【洛谷P3761】 [TJOI2017]城市

    P3761 [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公 ...

  7. [TJOI2017]城市(树的直径)

    [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公路相互可达, ...

  8. BZOJ4890 & 洛谷3761:[TJOI2017]城市——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4890 https://www.luogu.org/problemnew/show/P3761 从加 ...

  9. [bzoj 4887] [Tjoi2017]可乐

    传送门 Description 加里敦星球的人们特别喜欢喝可乐.因而,他们的敌对星球研发出了一个可乐机器人,并且 放在了加里敦星球的1号城市上.这个可乐机器人有三种行为:停在原地,去下一个相邻的 城市 ...

随机推荐

  1. 使用第三方库连接MySql数据库:PyMysql库和Pandas库

    使用PyMysql库和Pandas库链接Mysql 1 系统环境 系统版本:Win10 64位 Mysql版本: 8.0.15 MySQL Community Server - GPL pymysql ...

  2. C#调用COM组件遇到的问题及解决办法

    1.无法嵌入互操作类型"xxx",请改用适用的接口. 解决办法: - 将所引用的程序集的[嵌入互操作类型]属性设置为[False]. 2.System.Runtime.Intero ...

  3. (转)Linux下安装Android的adb驱动-解决不能识别的问题(国产板子)

    注:本文不涉及怎么安装adb等工具.本方法通用.到目前为止已经解决rk3188和展讯SC6820(波导T9500)的识别问题. 以前调试的Android板子,都是直接用的Google的usb设备id, ...

  4. centos7用fdisk进行分区

    1.查看分区信息:fdisk -l 从上面可以看到,/dev/sdb分区还没有使用,现在将其划分成2个10G的分区. 2.执行:fdisk /dev/sdb 1):fdisk命令参数 p:打印分区表. ...

  5. (I/O流)在100ms内桌面上生成一个200M大小的文件

    最终速度取决于硬盘的读写速度 package com.laurdawn; import java.io.File; import java.io.FileInputStream; import jav ...

  6. up6-自定义文件存储路径

    在up6.2中有两种保存模式,一种是md5一种是uuid. md5由PathMd5Builder生成存储路径.md5主要提供给文件使用,可在服务器端保存唯一的文件,有效避免重复文件. uuid由Pat ...

  7. OpenSSH免密码登录SSH2

    SSH2免密码登录OpenSSHhttp://blog.csdn.net/aquester/article/details/23836299 两个SSH2间免密码登录http://blog.csdn. ...

  8. 编写高质量代码改善C#程序的157个建议——建议80:用Task代替ThreadPool

    建议80:用Task代替ThreadPool ThreadPool相对于Thread来说具有很多优势,但是ThreadPool在使用上却存在一定的不方便.比如: ThreadPool不支持线程的取消. ...

  9. 团体程序设计天梯赛L1-025 正整数A+B 2017-03-23 22:47 61人阅读 评论(0) 收藏

    L1-025. 正整数A+B 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 本题的目标很简单,就是求两个正整数A和B的和,其中 ...

  10. bootstrap css排版

    smart-form 单行元素: 一般用div包含,class="row" 列元素:用section包含,class="col col-x"(section带有 ...