2010年02月28日星期日.sgu149 tree dp

2010年02月28日星期日.sgu149 tree dp

2010年02月28日星期日.sgu149
sgu149:tree dp
这个题想了好久,第一遍代码写的太乱了,然后就重新写了一遍,还好过了。。

思路就是每个点的最长距离有两个来源,一个是子节点,一个是父节点。
字节点的即是深度,这个好求。
如果是来自父节点,那么假定父节点的最长距离已经获得,
如果这个最长距离不是来自当前节点,就可一直接加上父节点到这个节点的边长。
如果这个最长距离恰好来自这个节点,那么可以使用父节点不来自这个节点的最长路来做同样的事情。

 1 
 2  #define  pb(x) push_back(x)
 3  const   int  N  =   10100 ;
 4  vector < int >  g[N];
 5  int  deep[N],n,far1[N],far2[N],branch[N],vis[N];
 6  int   out [N];
 7 
 8  void  dfs1( int  u)
 9  {
10    vis[u]  =   true ;
11     int  res  =   0 ,idx  =   0 ;
12     for  ( int  i  =   0 ;i  <  g[u].size();i  += 2  ) {
13         int  v  =  g[u][i];
14         int  w  =  g[u][i + 1 ];
15         if  ( ! vis[v]) {
16            dfs1(v);
17             if  (res  <  deep[v]  +  w) {
18                res  =  deep[v]  +  w;
19                idx  =  v;
20            }
21        }
22    }
23    deep[u]  =  res;
24  }
25 
26  void  dfs2( int  u, int  cost)  //  u is current  //  cost from parent
27  {
28    vis[u]  =   true ;
29    branch[u]  =   0 ;
30    far1[u]  =  cost;
31    far2[u]  =   0 ;
32 
33     int  i,sz  =  g[u].size();
34     for  (i  =   0 ;i  <  sz;i  +=   2 ) {
35         int  v  =  g[u][i];
36         int  w  =  g[u][i + 1 ];
37         if  (vis[v]) {  continue ; }  // !
38         if  (far1[u]  <  deep[v]  +  w ) {
39            far2[u]  =  far1[u];
40            far1[u]  =  deep[v]  +  w ;
41            branch[u]  =  v;
42        } else   if  (far2[u]  <  deep[v]  +  w ) {
43            far2[u]  =  deep[v]  +  w;
44        }
45    }
46     // http://www.cppblog.com/schindlerlee
47     for  (i  =   0 ;i  <  sz;i  +=   2 ) {
48         int  v  =  g[u][i];
49         int  w  =  g[u][i + 1 ];
50         if  (vis[v]) {  continue ; }
51         if  (v  !=  branch[u]) {
52            dfs2(v,far1[u]  +  w);
53        } else  {
54            dfs2(v,far2[u]  +  w);
55        }
56    }
57  }
58 
59  int  main()
60  {
61     int  i,j,k,a,b;
62    scanf( " %d " , & n);
63     for  (i  =   2 ;i  <=  n;i ++ ) {
64        scanf( " %d%d " , & a, & b);
65        g[i].pb(a),g[i].pb(b);
66        g[a].pb(i),g[a].pb(b);
67    }
68    dfs1( 1 );
69    memset(vis, 0 , sizeof (vis));
70    dfs2( 1 , 0 );
71     for  ( i  =   1 ; i  <=  n; i ++ ) {
72        printf( " %d\n " ,far1[i]);
73    }
74 
75     return   0 ;
76  }
77 

你可能感兴趣的:(2010年02月28日星期日.sgu149 tree dp)