传送门

$ \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. Verifying Package Integrity Using MD5 Checksums or GnuPG

    In this note, I reference the MySQL manual file. After downloading the MySQL package that suits your ...

  2. Python爬虫入门六之Cookie的使用

    大家好哈,上一节我们研究了一下爬虫的异常处理问题,那么接下来我们一起来看一下Cookie的使用. 为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在 ...

  3. Greeplum 系列(二) 安装部署

    Greeplum 系列(二) 安装部署 本章将介绍如何快速安装部署 Greenplum,以及 Greenplum 的一些常用命令及工具.本章不会涉及硬件选型.操作系统参数讲解.机器性能测试等高级内容, ...

  4. Excel中使用VBA访问Access数据库

    VBA访问Access数据库 1. 通用自动化语言VBA VBA(Visual Basic For Application)是一种通用自动化语言,它可以使Excel中的常用操作自动化,还可以创建自定义 ...

  5. Spring.net页面属性注入

    .条件spring.web程序集 1.1 system.web配置 <httpHandlers> <add verb="*" path="*.aspx& ...

  6. poj 2007 Scrambled Polygon

    #include<stdio.h> #include<algorithm> using namespace std; #define Max 60 struct Point { ...

  7. MySQL 存储过程和存储函数学习

    #一.存储过程和存储函数的创建案例 CREATE PROCEDURE myprocedure(in a int,in b int ,OUT c INT) BEGIN set c=a+b; end; c ...

  8. [转]修改github已提交的用户名和邮箱

    改变作者信息 为改变已经存在的 commit 的用户名和/或邮箱地址,你必须重写你 Git repo 的整个历史. 警告:这种行为对你的 repo 的历史具有破坏性.如果你的 repo 是与他人协同工 ...

  9. gitlab 升级到 5.3 之后不能pull

    升级gitlab到5.3之后pull出现下面的错误: /usr/local/lib/ruby/1.9.1/net/protocol.rb:146:in `rescue in rbuf_fill': T ...

  10. SuSE Linux上修改主机名

    1) 临时修改主机名 临时修改使用hostname即可,格式为:hostname 新主机名.Hostname命令除可以临时修改主机名外,还可以用它来查看主机名,不带参数执行它,即为查看主机名. 2)  ...