zoukankan      html  css  js  c++  java
  • HDU2196 树形DP

    Computer

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5903    Accepted Submission(s): 2963


    Problem Description
    A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.


    Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
     
    Input
    Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.
     
    Output
    For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).
     
    Sample Input
    5 1 1 2 1 3 1 1 1
     
    Sample Output
    3 2 3 4 4
     
    Author
    scnu
     
    题意:
    第一台电脑是根节点,给出若干台电脑与电脑之间的距离,问每一台电脑与其他电脑之间的最大距离。
    代码:
      1 /*
      2 某一节点的最大距离可以由他的子树中得来也可以由他的父亲得来,如果由他父亲得来,他父亲的最大值可能是从他那
      3 里来的,如果是这样就要用他父亲的次最大值,所以每一节点要找到最大值和次最大值,用两次搜索确定最大值。
      4 */
      5 #include<iostream>
      6 #include<string>
      7 #include<cstdio>
      8 #include<cmath>
      9 #include<cstring>
     10 #include<algorithm>
     11 #include<vector>
     12 #include<iomanip>
     13 #include<queue>
     14 #include<stack>
     15 using namespace std;
     16 int n,head[20010],dp[20010][4];//表示到那个结点,j=0表示到此节点的最大值,j=1表示到此节点的次最大值
     17 //j=2表示到此节点的最大值的情况下的子节点,j=3表示到此节点的次最大值的情况下的子节点。
     18 int lne;
     19 struct node
     20 {
     21     int to,next,val;
     22 }tree[20010];
     23 void add(int u,int v,int w)
     24 {
     25     tree[lne].to=v;
     26     tree[lne].val=w;
     27     tree[lne].next=head[u];
     28     head[u]=lne++;
     29     tree[lne].to=u;
     30     tree[lne].val=w;
     31     tree[lne].next=head[v];
     32     head[v]=lne++;
     33 }
     34 void dfs1(int root,int pre)
     35 {
     36     for(int i=head[root];i!=-1;i=tree[i].next)
     37     {
     38         int son=tree[i].to;
     39         if(son==pre)
     40         continue;
     41         dfs1(son,root);
     42         if(dp[root][0]<dp[son][0]+tree[i].val)
     43         {
     44             dp[root][1]=dp[root][0];//把最大值赋给次最大值
     45             dp[root][3]=dp[root][2];//最大值的子节点给次最大值
     46             dp[root][0]=dp[son][0]+tree[i].val;//赋上新的最大值
     47             dp[root][2]=son;//新最大值的子节点
     48         }
     49         else if(dp[root][1]<dp[son][0]+tree[i].val)
     50         {
     51             dp[root][1]=dp[son][0]+tree[i].val;
     52             dp[root][3]=son;
     53         }
     54     }
     55 }
     56 void dfs2(int root,int pre)
     57 {
     58     for(int i=head[root];i!=-1;i=tree[i].next)
     59     {
     60         int son=tree[i].to;
     61         if(son==pre)
     62         continue;
     63         if(son==dp[root][2])//如果root的最大值是由son点来的,son的最大值就不能被更新位root的最大值,而是
     64                             //root的次最大值
     65         {
     66             if(dp[son][0]<dp[root][1]+tree[i].val)
     67             {
     68                 dp[son][1]=dp[son][0];
     69                 dp[son][3]=dp[son][2];
     70                 dp[son][0]=dp[root][1]+tree[i].val;
     71                 dp[son][2]=root;
     72             }
     73             else if(dp[son][1]<dp[root][1]+tree[i].val)
     74             {
     75                 dp[son][1]=dp[root][1]+tree[i].val;
     76                 dp[son][3]=root;
     77             }
     78         }
     79         else
     80         {
     81             if(dp[son][0]<dp[root][0]+tree[i].val)
     82             {
     83                 dp[son][1]=dp[son][0];
     84                 dp[son][3]=dp[son][2];
     85                 dp[son][0]=dp[root][0]+tree[i].val;
     86                 dp[son][2]=root;
     87             }
     88             else if(dp[son][1]<dp[root][0]+tree[i].val)
     89             {
     90                 dp[son][1]=dp[root][0]+tree[i].val;
     91                 dp[son][3]=root;
     92             }
     93         }
     94         dfs2(son,root);
     95     }
     96 }
     97 int main()
     98 {
     99     int v,w;
    100     while(scanf("%d",&n)!=EOF)
    101     {
    102         lne=0;
    103         memset(head,-1,sizeof(head));
    104         memset(dp,0,sizeof(dp));
    105         for(int i=2;i<=n;i++)
    106         {
    107             scanf("%d%d",&v,&w);
    108             add(i,v,w);
    109             dp[i][2]=i;
    110             dp[i][3]=i;
    111         }
    112         dfs1(1,0);
    113         dfs2(1,0);
    114         for(int i=1;i<=n;i++)
    115         {
    116             printf("%d
    ",dp[i][0]);
    117         }
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    STDMETHOD_,STDMETHOD,__declspec(novtable)和__declspec(selectany)
    __stdcall 与 __cdecl
    winows 进程通信的实例详解
    Windows 下多线程编程技术
    MFC/VC++ UI界面美化技术
    VC++中 wstring和string的互相转换实现
    VS2010项目转化为VS2008项目
    VC++ 响应回车键的2种方法
    高效 告别996,开启java高效编程之门 2-4实战:单一条件参数化
    高效 告别996,开启java高效编程之门 2-3实战:硬编码业务逻辑
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/5783259.html
Copyright © 2011-2022 走看看