zoukankan      html  css  js  c++  java
  • bzoj3124

    树形dp

    先拎出来一条直径,然后看直径上挂着的每条链,如果等于左边就把左端点放过来,等于右端点就把右端点放过来

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 2e5 + 5;
    struct edge {
        int nxt, to, w;
    } e[N << 1];
    int n, cnt = 1, ans;
    ll dis[N];
    int head[N], q[N], pre[N], mark[N];
    int read() 
    {
        int x = 0, f = 1; char c = getchar();
        while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    void link(int u, int v, int w) 
    {
        e[++cnt].nxt = head[u];
        head[u] = cnt;
        e[cnt].to = v;
        e[cnt].w = w;
    }
    int bfs(int s) 
    {
        int ret = s;
        memset(dis, -1, sizeof(dis));
        dis[s] = 0;
        int l = 1, r = 0;
        q[++r] = s;
        while(l <= r)
        {
            int u = q[l++];
            for(int i = head[u]; i; i = e[i].nxt) if(dis[e[i].to] == -1)  
            {
                dis[e[i].to] = dis[u] + e[i].w;
                q[++r] = e[i].to;
                pre[e[i].to] = u;
                if(dis[e[i].to] > dis[ret]) ret = e[i].to;
            }
        }
        return ret;
    }
    ll dfs(int u, int last)
    {
        ll ret = 0;
        for(int i = head[u]; i; i = e[i].nxt) if(e[i].to != last && !mark[e[i].to])
            ret = max(ret, dfs(e[i].to, u) + e[i].w);
        return ret;
    } 
    int main()
    {
        n = read();
        for(int i = 1; i < n; ++i)
        {
            int u = read(), v = read(), w = read();
            link(u, v, w);
            link(v, u, w);
        }
        int s = bfs(1), t = bfs(s);
        printf("%lld
    ", dis[t]);
        for(int i = t; i != s; i = pre[i]) mark[i] = 1;
        mark[s] = 1;
        int left = s, right = t, flag = 1;
        for(int i = t; i != s; i = pre[i]) 
        {
            ll d = dfs(i, 0);
            if(d == dis[i]) 
            {
                left = i;
                flag = 0;
            } 
            if(d == dis[t] - dis[i]) right = i;
        }
        for(int i = right; i != left; i = pre[i]) ++ans;
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Hadoop的MapReduce基本框架
    通过idea测试Hadoop增删改查
    Linux系统简介以及基本操作(二)
    Linux系统简介以及基本操作(一)
    JAVA解除tomcat 对浏览器特别字符 | () {} [] 的限制
    JAVA实现读取图片
    用java实现取1-100之间的99个不重复的随机数 然后输出没有被取出的数字
    < Android Camera2 HAL3 学习文档 >
    算法<初级>
    算法<初级>
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7791776.html
Copyright © 2011-2022 走看看