zoukankan      html  css  js  c++  java
  • Hdu 2196

    即求树上每点的最长路,先求出树的直径上的一点(dfs、bfs均可,寻找第一点我用的bfs),然后再从这点搜出树直径的另一点。可以证明每点的最长路是到这两点的距离之一(因为树是连通的,因为是树的直径,如果某点s到直径某点t的距离小于到另一点u的距离,那么u就可以代替t成为树的直径了。

    本题恶心的是内存限制,一开始采用边表老是超内存,后来把数组改为short后还不行,根据树的性质(E=V-1)使用数组链表,结果length可以超过short又忘了把short改为int就彻底悲剧了。。T^T

    #include <stdio.h>
    #include <string.h>
    
    #define _END    0x4f4f
    int pass[20005], head[10005];
    int v[20010], dis[20010], xdis;
    int dp0[10005], dp1[16384], *dp;
    int f, r;
    
    void dfs(int n)
    {
        int i, j;
        if (dp[n] > dp[xdis]) xdis = n;
        for(i=head[n]; i<_END; i = pass[i]) {
            if (dp[j = v[i]] == -1) {
                dp[j] = dp[n] + dis[i];
                dfs(j);
            }
        }
    }
    
    #define max(a,b) ((a)>(b) ? (a) : (b))
    
    int main(void)
    {
        int N;
        while(scanf("%d", &N) > 0) {
            int i, j, k;
            i = 0;
            memset(head, _END, sizeof(head));
            for(j=1; j<N; ++j) {
                int l;
                scanf("%d%d", &k, &l); --k;
                pass[i] = head[j], v[i] = k, dis[i] = l; head[j] = i++;
                pass[i] = head[k], v[i] = j, dis[i] = l; head[k] = i++;
            }
            memset(dp = dp0, -1, sizeof(int) * N);
            int mx;
            #define q dp1
            mx = dp[0] = q[f = 0] = 0, r = 1;
            while(f != r) {
                j = q[f];
                if (dp[j] > dp[mx]) mx = j;
                int l;
                for(k=head[j]; k<_END; k = pass[k]) {
                    l = v[k];
                    if (dp[l] == -1) {
                        dp[q[r] = l] = dp[j] + dis[k];
                        r = (r+1) & 16383;
                    }
                }
                f = (f+1) & 16383;
            }
            #undef q
            memset(dp, -1, sizeof(int) * N);
            dp[mx] = 0;    dfs(xdis = mx);
            memset(dp = dp1, -1, sizeof(int) * N);
            dp[xdis] = 0; dfs(xdis);
            for(j=0; j<N; ++j)
                printf("%d
    ", max(dp0[j], dp1[j]));
        }
        return 0;
    }
  • 相关阅读:
    ThinkPhp学习11
    ThinkPhp学习10
    1.自我介绍
    Axure高级教程--在原型中插入视频
    Axure制作iphone手机交互模型—覆盖切换
    对产品的一些总结
    详解Axure的Masters功能
    详解使用Axure 制作Tab切换功能
    产品经理的初识
    作为产品经理--如何写好PRD文档
  • 原文地址:https://www.cnblogs.com/e0e1e/p/hdu_2196.html
Copyright © 2011-2022 走看看