中南大学oj 1317 Find the max Link 边权可以为负的树上最长路 树形dp 不能两遍dfs

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1317
经典问题:
树上最长路,边权可以为负值的,树形dp,不能用两边dfs。
反例:
5 4
1 2 2
2 3 1
2 4 -100
4 5 10
写树形dp的时候,WA了好多次,错误在于:
记录单链的时候,一个节点的最长单链不一定等于:边权+孩子的最长单链
还可以不选孩子,只要边权就行!!!!!!
如果边权非负的话,就是 边权+孩子的最长单链 了。

思路:

  dp[u][0],记录的是以u为根结点的子树中的最长路

  dp[u][1],记录的是以u为起点的向下的一条最长链

转移时:

  a记录的是max{ dp[sons][0] } 

  b和c记录的分别是dp[sons][1]的最大值和次大值

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<vector>
 4 using namespace std;
 5 const int N = 50005;
 6 typedef long long LL;
 7 LL inf = N * 100000ll;
 8 
 9 inline LL max(LL a,LL b)    {return a>b?a:b;}
10 inline LL max(LL a,LL b,LL c)    {return (a>b?a:b)>c?(a>b?a:b):c;}
11 
12 LL dp[N][2];
13 vector<int> G[N];
14 struct edge
15 {
16     int to,w;
17 }edges[2*N];
18 
19 void dfs(int u,int fa)
20 {
21     int sz=G[u].size(),v,w;
22     LL temp;
23     LL a=-inf,b=-inf,c=-inf;
24     for(int i=0;i<sz;i++)
25     {
26         v = edges[G[u][i]].to;
27         w = edges[G[u][i]].w;
28         if( v!=fa )
29         {            
30             dfs(v,u);
31             temp = max(dp[v][1]+w,w);
32             a = max(a,dp[v][0]);
33             if( temp > b )
34             {
35                 c = b;
36                 b = temp;
37             }
38             else if( temp > c )
39                 c = temp;            
40         }
41     }
42     dp[u][0]=max(a,b,b+c);
43     dp[u][1]=b;
44 }
45 
46 int main()
47 {
48     int n,m;
49     int u,v,w;
50     
51     while( ~scanf("%d%d",&n,&m) )
52     {
53         for(int i=1;i<=n;i++)    G[i].clear();
54         for(int i=1;i<=m;i++)
55         {
56             scanf("%d%d%d",&u,&v,&w);
57             edges[i].to = v;
58             edges[i+m].to = u;
59             edges[i].w = edges[i+m].w = w;
60             G[u].push_back(i);
61             G[v].push_back(i+m);
62         }
63         dfs(1,0);
64         LL ans = -inf;
65         for(int i=1;i<=n;i++)
66             ans = max(ans,dp[i][0]);
67         printf("%lld\n",ans);
68         //cout<<ans<<endl;
69     }
70     return 0;
71 }
View Code

 

posted @ 2013-09-01 14:15  kiwi_bird  阅读(458)  评论(0编辑  收藏  举报