zoukankan      html  css  js  c++  java
  • HDU 2196 Computer

    http://acm.hdu.edu.cn/showproblem.php?pid=2196

    题意:

    给出一棵树,求出每个点到其他点的最远距离。

    思路:
    对于每一个点,一方面它可以往它的子树方向走,另一方面可以往父亲结点的方向走。所以我们需要两次dfs,第一次用来求出每个点往其子树方向的最远距离和次远距离,为什么要计算出次远距离呢,因为在第二次dfs求父亲结点方向时,可能父亲结点的最大值经过了这个点,此时需要更换路线使得它不经过这个点。

    #include<iostream> 
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    #define N 10001
    
    int n;
    
    struct node
    {
        int to;    //终点
        int next;  //下一条同样起点的边
        int w;     //权值
    }edge[N*2];
    
    int tol;
    int head[N];  //头结点,邻接链表存储
    
    int dist[N][3];   //dist[N][0]代表正向最远距离,[N][1]代表正向次远距离,[N][2]代表反向最远距离
    int flag[N];
    
    //邻接链表存储,加入到链表的首部
    void add_edge(int u, int v, int w)
    {
        edge[tol].to = v;
        edge[tol].w = w;
        edge[tol].next = head[u];
        head[u] = tol++;
        edge[tol].to = u;
        edge[tol].w = w;
        edge[tol].next = head[v];
        head[v] = tol++;
    }
    
    
    int dfs1(int u, int fa)
    {
        if (dist[u][0] != -1)  return dist[u][0];
        dist[u][0] = dist[u][1] = 0;
        
        for (int e = head[u]; e != -1; e = edge[e].next)
        {
            int v = edge[e].to;
            if (v == fa)   continue;
            dfs1(v, u);
            if (dist[u][0] < dist[v][0] + edge[e].w)
            {
                flag[u] = v;
                dist[u][1] = dist[u][0];               //更新次远距离
                dist[u][0] = dist[v][0] + edge[e].w;   //更新最远距离
            }
            //这个不能忘,比最远距离小但可能比次远距离大,此时需要更新次远距离
            else if (dist[u][1] < dist[v][0] + edge[e].w)
                dist[u][1] = dist[v][0] + edge[e].w;
        }
        return dist[u][0];
    }
    
    
    void dfs2(int u, int fa)
    {
        for (int e = head[u]; e != -1; e = edge[e].next)
        {
            int v = edge[e].to;
            if (v == fa)  continue;
            if (v == flag[u])  dist[v][2] = max(dist[u][2], dist[u][1]) + edge[e].w;
            else dist[v][2] = max(dist[u][2], dist[u][0]) + edge[e].w;
            dfs2(v, u);
        }
    }
    
    int main()
    {
        //freopen("D:\txt.txt", "r", stdin);
        int v, w;
        while (~scanf("%d", &n) && n)
        {
            tol = 0;
            memset(head, -1, sizeof(head));
            memset(dist, -1, sizeof(dist));
            memset(flag, -1, sizeof(flag));
            for (int i = 2; i <= n; i++)
            {
                scanf("%d%d", &v, &w);
                add_edge(i, v, w);    //存边
            }
    
            dfs1(1, -1);
            dfs2(1, -1);
            for (int i = 1; i <= n; i++)
                printf("%d
    ", max(dist[i][0], dist[i][2]));
        }
        return 0;
    }
  • 相关阅读:
    (转)jQuery.extend 函数详解
    (转)跟我一起学JQuery插件开发教程
    (转)jQuery插件开发全解析
    (转)弹出窗口lhgDialog API文档
    (转)反射发送实战(-)InvokeMember
    (转)JQuery处理json与ajax返回JSON实例
    linux下添加用户并赋予root权限
    Linux 下配置,安装Hadoop
    Linux 下安装 jdk-7u79-linux-x64.gz,jdk1.7.0_79,jdk1.7步骤:
    linux下导入、导出mysql数据库命令
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6391668.html
Copyright © 2011-2022 走看看