• [BZOJ1509][NOI2003]逃学的小孩


    1509: [NOI2003]逃学的小孩

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 968  Solved: 489
    [Submit][Status][Discuss]

    Description

    Input

    第一行是两个整数N(3  N  200000)和M,分别表示居住点总数和街道总数。以下M行,每行给出一条街道的信息。第i+1行包含整数Ui、Vi、Ti(1Ui, Vi  N,1  Ti  1000000000),表示街道i连接居住点Ui和Vi,并且经过街道i需花费Ti分钟。街道信息不会重复给出。

    Output

    仅包含整数T,即最坏情况下Chris的父母需要花费T分钟才能找到Chris。

    Sample Input

    4 3
    1 2 1
    2 3 1
    3 4 1

    Sample Output

    4
     
    枚举每个点为三条路径的交点,设到这个点的第一、二、三长链的长度分别为$x,y,z$,则最长路径为$x+2*y+z$
    注意可能从父亲那里有一条链连过来,所以dfs两遍
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    char buf[10000000], *ptr = buf - 1;
    inline int readint() {
        int n = 0;
        char ch = *++ptr;
        while (ch< '0' || ch > '9') ch = *++ptr;
        while (ch <= '9' && ch >= '0') {
            n = (n << 1) + (n << 3) + ch - '0';
            ch = *++ptr;
        }
        return n;
    }
    typedef long long ll;
    const int maxn = 200000 + 10;
    const ll INF = 1LL << 60;
    struct Edge {
        int to, val, next;
        Edge() {}
        Edge(int _t, int _v, int _n) : to(_t), val(_v), next(_n) {}
    }e[maxn * 2];
    int fir[maxn] = { 0 }, cnt = 0;
    inline void ins(int u, int v, int w) {
        e[++cnt] = Edge(v, w, fir[u]); fir[u] = cnt;
        e[++cnt] = Edge(u, w, fir[v]); fir[v] = cnt;
    }
    int fa[maxn];
    ll mx1[maxn], mx2[maxn], mx3[maxn], f[maxn];
    void dfs1(int u) {
        mx1[u] = mx2[u] = mx3[u] = 0;
        for (int v, i = fir[u]; i; i = e[i].next) {
            v = e[i].to;
            if (v == fa[u]) continue;
            fa[v] = u;
            dfs1(v);
            mx3[u] = max(mx3[u], mx1[v] + e[i].val);
            if (mx3[u] > mx2[u]) swap(mx3[u], mx2[u]);
            if (mx2[u] > mx1[u]) swap(mx2[u], mx1[u]);
        }
    }
    void dfs2(int u) {
        for (int v, i = fir[u]; i; i = e[i].next) {
            v = e[i].to;
            if (v == fa[u]) continue;
            f[v] = f[u] + e[i].val;
            if (mx1[v] + e[i].val == mx1[u])
                f[v] = max(f[v], mx2[u] + e[i].val);
            else
                f[v] = max(f[v], mx1[u] + e[i].val);
            dfs2(v);
        }
    }
    ll ans = 0;
    inline void solve(ll &x, ll &y, ll &z) {
        if (z > y) swap(z, y);
        if (y > x) swap(y, x);
        ans = max(ans, x + (y << 1) + z);
    }
    int main() {
        fread(buf, sizeof(char), sizeof(buf), stdin);
        int n = readint();
        readint();
        for (int u, v, w, i = 1; i < n; i++) {
            u = readint();
            v = readint();
            w = readint();
            ins(u, v, w);
        }
        fa[1] = 0;
        dfs1(1);
        f[1] = 0;
        dfs2(1);
        for (int i = 1; i <= n; i++)
            if (f[i] < mx3[i]) solve(mx1[i], mx2[i], mx3[i]);
            else solve(mx1[i], mx2[i], f[i]);
        printf("%lld
    ", ans);
        return 0;
    }
  • 相关阅读:
    变量和基本数据类型,深浅拷贝问题
    计算机系统与编程语言分类
    关于计算机硬件的基本知识
    Python学习之路——函数
    Python学习之路——Day06 元组
    day--07
    数据类型——可变不可变类型
    数字类型
    流程控制——while循环
    流程控制——if判断
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7612276.html
Copyright © 2020-2023  润新知