• hdu2196Computer 树形DP


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196

    思路:

    一看就是一道树形DP的题目,对于一个节点来说,到它的最远距离的路径可能来于子树,也可能来源于经过父亲节点的路径,所以我们两次DFS即可。

    第一次DFS自底向上(从叶节点开始),依次求出每个节点的在其子树上的最大距离和次大距离

    第二次DFS自顶向下(从根节点开始),通过比较经过父亲节点的路径的最大距离和来源于子树的最大距离比较然后更新最大距离

    至于为什么要保存次大距离呢??因为经过父亲节点的最大距离可能刚好经过当前的孩子节点,那么我们就只能通过当前孩子到父亲节点的距离加上经过父亲节点的路径次大值和当前节点的位于其子树的路径的最大距离的比较来更新最大距离咯。

    虽然思路还是比较清晰的,自己实现起来还是比较难的。。。。

    代码如下:

      1 #include<cstdlib>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<iostream>
      5 using namespace std;
      6 #define MAX 10010
      7 class node
      8 {
      9    public:
     10    int to;
     11    int w;
     12    int next;
     13   
     14 };
     15 node edge[2*MAX];
     16 int head[MAX];
     17 int tol;
     18 int maxn[MAX];
     19 int smaxn[MAX];
     20 int m_id[MAX];
     21 int sm_id[MAX];
     22 int vis[MAX];
     23 void init()
     24 {
     25     memset(head,-1,sizeof(head));
     26     memset(maxn,0,sizeof(maxn));
     27     memset(smaxn,0,sizeof(smaxn));
     28     memset(vis,0,sizeof(vis));
     29     tol=0;
     30 }
     31 void Build_Tree(int  u,int v,int w)
     32 {
     33     edge[tol].to=v;
     34     edge[tol].w=w;
     35     edge[tol].next=head[u];
     36     head[u]=tol++;
     37 }
     38 void dfs1(int root,int parent)
     39 {
     40         vis[root]=1;
     41         for(int i=head[root];i!=-1;i=edge[i].next)
     42         {
     43           if(vis[edge[i].to]) continue;
     44           int son=edge[i].to;
     45           dfs1(son,root);
     46           int len=edge[i].w;
     47           if(smaxn[root]<maxn[son]+len)
     48           {
     49               smaxn[root]=maxn[son]+len;
     50               sm_id[root]=son;
     51               if(smaxn[root]>maxn[root])
     52               {
     53                     swap(smaxn[root],maxn[root]);
     54                     swap(sm_id[root],m_id[root]);
     55               }
     56           }
     57         }
     58 }
     59 void dfs2(int root ,int  parent)
     60 {
     61     for(int i=head[root];i!=-1;i=edge[i].next)
     62     {
     63          if(edge[i].to==parent) continue;
     64          int son=edge[i].to;
     65          if(m_id[root]==son)
     66          {
     67               if(edge[i].w+smaxn[root]>smaxn[son])
     68               {
     69                     smaxn[son]=edge[i].w+smaxn[root];
     70                     sm_id[son]=root;
     71                     if(smaxn[son]>maxn[son])
     72                     {
     73                          swap(smaxn[son],maxn[son]);
     74                          swap(sm_id[son],m_id[son]);
     75                     }
     76               }
     77          }
     78          else
     79         {
     80             if(edge[i].w+maxn[root]>smaxn[son])
     81             {
     82                 smaxn[son]=edge[i].w+maxn[root];
     83                 sm_id[son]=root;
     84                 if(smaxn[son]>maxn[son])
     85                 {
     86                     swap(smaxn[son],maxn[son]);
     87                     swap(m_id[son],sm_id[son]);
     88                 }
     89             }
     90         }
     91         dfs2(son,root);
     92     }
     93 
     94 }
     95 int n;
     96 int main()
     97 {
     98         while(scanf("%d",&n)!=EOF)
     99         {
    100             init();
    101            for(int i=2;i<=n;i++)
    102            {
    103               int u,w;
    104               scanf("%d%d",&u,&w);
    105               Build_Tree(i,u,w);
    106               Build_Tree(u,i,w);
    107            }
    108            dfs1(1,-1);
    109            dfs2(1,-1);
    110            for(int i=1;i<=n;i++)
    111              cout<<maxn[i]<<endl;
    112            
    113         }
    114         return 0;
    115  }
    View Code
  • 相关阅读:
    Android之ActionBar的样式使用
    Android之在View中执行Activity的跳转
    Android之百度定位API使用
    那些年掉进过的Android坑之Fragment系列
    Android UI设计框架[1]: ViewPager+Fragment实现底部图标文字的导航栏(IconTabPageIndicator)
    SQLite3初探
    【GDOI2018模拟7.9】期末考试
    【ZJOJ1321】灯
    【NOIP2016提高A组模拟8.23】函数
    【ZJOJ5186】【NOIP2017提高组模拟6.30】tty's home
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/hdu2196.html
Copyright © 2020-2023  润新知