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

    题目大意

    给你一颗边带权值的树,求树上的每一点距离其最远的一个点的距离

    分析

    经典的树形DP题。由于对于一个节点来说,可能得到的距离最大的值的路径来自他的子树,或者从他的父节点过来,所以用两次DFS。

    但是有个问题就是判断一个点的从父节点过来的最大值,那么如果他的父节点存的最大值正好是从该点过来的,那么就失去了从父节点过来的状态,所以要记录最大的两个值。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<string>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<set>
      8 #define MAXN 20010
      9 using namespace std;
     10 struct Node
     11 {
     12     int v,w;
     13     int next;
     14 }node[MAXN];
     15 int tot,n;
     16 int head[MAXN],maxn[MAXN],smaxn[MAXN],maxid[MAXN],smaxid[MAXN];
     17 void add(int u,int v,int w)
     18 {
     19     node[tot].v=v;
     20     node[tot].w=w;
     21     node[tot].next=head[u];
     22     head[u]=tot;
     23     tot++;
     24 }
     25 void dfs1(int u,int p)
     26 {
     27     maxn[u]=0;
     28     smaxn[u]=0;
     29     for(int i=head[u];i!=-1;i=node[i].next)
     30     {
     31         int v=node[i].v;
     32         if(v==p)
     33             continue;
     34         dfs1(v,u);
     35         if(smaxn[u]<maxn[v]+node[i].w)
     36         {
     37             smaxn[u]=maxn[v]+node[i].w;
     38             smaxid[u]=v;
     39             if(smaxn[u]>maxn[u])
     40             {
     41                 swap(smaxn[u],maxn[u]);
     42                 swap(smaxid[u],maxid[u]);
     43             }
     44         }
     45     }
     46 }
     47 void dfs2(int u,int p)
     48 {
     49     for(int i=head[u];i!=-1;i=node[i].next)
     50     {
     51         int v=node[i].v;
     52         if(v==p)
     53             continue;
     54         if(v==maxid[u])
     55         {
     56             if(node[i].w+smaxn[u]>smaxn[v])
     57             {
     58 
     59                 smaxn[v]=node[i].w+smaxn[u];
     60                 smaxid[v]=u;
     61                 if(smaxn[v]>maxn[v])
     62                 {
     63                     swap(smaxn[v],maxn[v]);
     64                     swap(smaxid[v],maxid[v]);
     65                 }
     66             }
     67         }
     68         else
     69         {
     70             if(node[i].w+maxn[u]>smaxn[v])
     71             {
     72                 smaxn[v]=node[i].w+maxn[u];
     73                 smaxid[v]=u;
     74                 if(smaxn[v]>maxn[v])
     75                 {
     76                     swap(smaxn[v],maxn[v]);
     77                     swap(maxid[v],smaxid[v]);
     78                 }
     79             }
     80         }
     81         dfs2(v,u);
     82 
     83     }
     84 }
     85 int main()
     86 {
     87     while(scanf("%d",&n)!=EOF)
     88     {
     89         tot=0;
     90         int v,w;
     91         memset(head,-1,sizeof(head));
     92         for(int i=2;i<=n;i++)
     93         {
     94             scanf("%d %d",&v,&w);
     95             add(i,v,w);
     96             add(v,i,w);
     97         }
     98         dfs1(1,-1);
     99         dfs2(1,-1);
    100         for(int i=1;i<=n;i++)
    101             printf("%d
    ",maxn[i]);
    102 
    103     }
    104     return 0;
    105 }

    图是用邻接表保存的,不理解的可以看看我的上一篇博客

  • 相关阅读:
    javascript 调试代码
    简洁的js拖拽代码
    搭个小窝
    FastDFS随笔
    JDK6和JDK7中String的substring()方法及其差异
    杂笔
    JVM内存随笔
    java中的final和volatile详解
    关于java的Synchronized,你可能需要知道这些(下)
    关于java的Synchronized,你可能需要知道这些(上)
  • 原文地址:https://www.cnblogs.com/tsw123/p/4452049.html
Copyright © 2011-2022 走看看