zoukankan      html  css  js  c++  java
  • BZOJ 1509: [NOI2003]逃学的小孩( 树形dp )

    树形dp求出某个点的最长3条链a,b,c(a>=b>=c), 然后以这个点为交点的最优解一定是a+2b+c.好像还有一种做法是求出树的直径然后乱搞...

    ---------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
     
    using namespace std;
     
    typedef long long ll;
     
    const int maxn = 200009;
     
    int N;
    ll X[maxn], Y[maxn], Z[maxn], F[maxn], ans;
     
    struct edge {
    int to, w;
    edge* next;
    } E[maxn << 1], *pt = E, *head[maxn];
     
    void AddEdge(int u, int v, int w) {
    pt->to = v;
    pt->w = w;
    pt->next = head[u];
    head[u] = pt++;
    }
     
    inline int read() {
    char c = getchar();
    int ret = 0;
    for(; !isdigit(c); c = getchar());
    for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
    return ret;
    }
     
    void Init() {
    N = read();
    int m = read();
    while(m--) {
    int u = read() - 1, v = read() - 1, w = read();
    AddEdge(u, v, w);
    AddEdge(v, u, w);
    }
    }
     
    void DFS0(int x, int fa = -1) {
    X[x] = Y[x] = 0;
    for(edge* e = head[x]; e; e = e->next) if(e->to != fa) {
    DFS0(e->to, x);
    Z[x] = max(Z[x], X[e->to] + e->w);
    if(Z[x] > Y[x]) swap(Z[x], Y[x]);
    if(Y[x] > X[x]) swap(X[x], Y[x]);
    }
    }
     
    void DFS1(int x, int fa = -1) {
    for(edge* e = head[x]; e; e = e->next) if(e->to != fa) {
    F[e->to] = F[x] + e->w;
    if(X[e->to] + e->w == X[x])
    F[e->to] = max(F[e->to], Y[x] + e->w);
    else
    F[e->to] = max(F[e->to], X[x] + e->w);
    DFS1(e->to, x);
    }
    }
     
    inline void upd(ll &x, ll &y, ll &z) {
    if(y > x) swap(x, y);
    if(z > x) swap(x, z);
    if(z > y) swap(y, z);
    ans = max(x + (y << 1) + z, ans);
    }
     
    int main() {
    Init();
    DFS0(0);
    DFS1(F[0] = 0);
    ans = 0;
    for(int i = 0; i < N; i++)
    F[i] <= Z[i] ? upd(X[i], Y[i], Z[i]) : upd(X[i], Y[i], F[i]);
    printf("%lld ", ans);
    return 0;
    }

    --------------------------------------------------------------------- 

    1509: [NOI2003]逃学的小孩

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 528  Solved: 285
    [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

    HINT

    Source

  • 相关阅读:
    synchronized一个(二)
    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
    java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout
    NTFS簇大小对硬盘性能的影响测试
    Win10 开机自动打开上次未关闭程序怎么办
    Win10快速访问怎么关闭?
    激活windows 10 LTSC 2019(无需工具)
    WPS文字双行合一
    插入百度地图代码后,页面文字不能被选中的解决方案
    WPS文字批量选中整行(以第?章为例)
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5063206.html
Copyright © 2011-2022 走看看