zoukankan      html  css  js  c++  java
  • HDU 2196 Computer (树形DP)

    题意:给一棵树,问每个点到其他点的最远距离是多少?

    思路:

      按两次深搜,第一次求每个点的后代中最远的距离以及次远距离,第二次就可以从上往下逐个更新答案了。当一棵树形成了,那么每个点只有两个方向可能会有最远距离,一个是经过其父亲,一个是经过其某个孩子。当在第二次深搜时往下推时要注意,经过父亲到达本节点的,可能是从本节点的某个兄弟那里来的。

     1 #include <bits/stdc++.h>
     2 #define pii pair<int,int>
     3 #define INF 0x3f3f3f3f
     4 #define LL long long
     5 using namespace std;
     6 const int N=10010;
     7 int  ans[N], first[N][2], second[N][2], edge_cnt;
     8 
     9 struct node
    10 {
    11     int from,to;
    12     int len;
    13     node(){};
    14     node(int from,int to,int len):from(from),to(to),len(len){};
    15 }edge[N*2];
    16 vector<int> tree[N];
    17 
    18 void add_edge(int from,int to,int len)
    19 {
    20     edge[edge_cnt]=node(from,to,len);
    21     tree[from].push_back(edge_cnt++);
    22 }
    23 
    24 bool vis[N];
    25 int DFS1(int t)    //从下往上
    26 {
    27     vis[t]=1;
    28     for(int i=0; i<tree[t].size(); i++)
    29     {
    30         node e=edge[tree[t][i]];
    31         if(!vis[e.to])
    32         {
    33             int sum=DFS1(e.to)+e.len;
    34             if(sum>second[t][0])
    35             {
    36                 second[t][0]=sum;
    37                 second[t][1]=e.to;
    38                 if(second[t][0]>first[t][0])    swap(second[t],first[t]);
    39             }
    40         }
    41     }
    42     return first[t][0];
    43 }
    44 
    45 void DFS2(int t,int up)     //从上往下
    46 {
    47     vis[t]=1;
    48     ans[t]=max(up, first[t][0]);
    49     for(int i=0; i<tree[t].size(); i++)
    50     {
    51         node e=edge[tree[t][i]];
    52         if(!vis[e.to])
    53         {
    54             if(first[t][1]==e.to)    DFS2(e.to, e.len+max(up, second[t][0]));
    55             else                     DFS2(e.to, e.len+max(up, first[t][0]));
    56         }
    57     }
    58 }
    59 
    60 int main()
    61 {
    62     //freopen("input.txt", "r", stdin);
    63     int n, a, b;
    64     while(cin>>n)
    65     {
    66         memset(second, 0, sizeof(second));
    67         memset(first, 0, sizeof(first));
    68         for(int i=0; i<=n; i++) tree[i].clear();
    69         edge_cnt=0;
    70         for(int i=2; i<=n; i++) //1号是主机
    71         {
    72             scanf("%d%d",&a,&b);
    73             add_edge(i,a,b);
    74             add_edge(a,i,b);
    75         }
    76         memset(vis,0,sizeof(vis));
    77         DFS1(1);
    78         memset(vis,0,sizeof(vis));
    79         DFS2(1,0);
    80         for(int i=1; i<=n; i++) printf("%d
    ", ans[i]);
    81     }
    82     return 0;
    83 }
    AC代码
  • 相关阅读:
    指针的引用
    引用的基础知识
    const的基础用法
    解决'fopen':this function or variable may be unsafe先关问题的方法
    C++类中不写成员函数易犯错模型
    PCB接地设计宝典:ADI资深专家总结的良好接地指导原则
    电路板级的电磁兼容性设计
    自然对流仿真设置
    Pspice 原理图以及仿真图 输出到 word
    信号完整性常见问题
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4806948.html
Copyright © 2011-2022 走看看