codeforces 743D【數dp】

連接:http://codeforces.com/contest/743/problem/Dios

題意:ide

給定n個結點的樹的每一個結點的權值,讓你找到兩個不相交的子樹的最大權值和;1爲根節點;spa

題解:code

首先了解一會兒樹的概念,百度一下就出來了。考慮以u爲根結點的子樹的最大權值,兩種狀況:blog

1.包含u的時候就是全部子樹的權值和tol;ci

2.不包含u的時候就是某顆權值最大的子樹;string

這樣的話dfs+dp即可以搞到全部以i爲根節點的最大權值子樹,這個時候再來想一想更新答案的事情;it

答案確定是某個結點的最大權值子樹+次大權值子樹,這樣子向上更新到1這個根節點的。io

那麼很顯然,在剛纔dfs+dp以後找到某個結點的最大和次大子樹便可,若是隻有一個子樹dp有了答案顯然不行,必須至少有兩個子樹都dp更新過答案;event

代碼:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <bitset>
 6 #include <vector>
 7 #include <queue>
 8 #include <stack>
 9 #include <cmath>
10 #include <list>
11 #include <set>
12 #include <map>
13 #define rep(i,a,b) for(int i = a;i <= b;++ i)
14 #define per(i,a,b) for(int i = a;i >= b;-- i)
15 #define mem(a,b) memset((a),(b),sizeof((a)))
16 #define FIN freopen("in.txt","r",stdin)
17 #define FOUT freopen("out.txt","w",stdout)
18 #define IO ios_base::sync_with_stdio(0),cin.tie(0)
19 #define mid ((l+r)>>1)
20 #define ls (id<<1)
21 #define rs ((id<<1)|1)
22 #define INFF  0x3f3f3f3f3f3f3f
23 using namespace std;
24 typedef long long LL;
25 typedef pair<int, int> PIR;
26 const int N = 2e5+5;
27 int n, u, v;
28 LL a[N], dp[N], ans;
29 vector <int> G[N];
30 LL dfs(int u, int pre){
31     LL sum = a[u], maxn1 = -INFF, maxn2 = -INFF;
32     rep(i, 0, (int)G[u].size()-1){
33         int v = G[u][i];
34         if(v == pre)    continue;
35         sum += dfs(v, u);
36         if(dp[v] > maxn1)   { maxn2 = maxn1; maxn1 = dp[v]; }
37         else if(dp[v] > maxn2)  maxn2 = dp[v];
38     }
39     if(maxn1 != -INFF && maxn2 != -INFF)    ans = max(ans, maxn1+maxn2);
40     dp[u] = max(maxn1, sum);
41     return sum;
42 }
43 int main()
44 {IO;
45     //FIN;
46     while(cin >> n){
47         rep(i, 0, n)    G[i].clear();
48         rep(i, 1, n)    cin >> a[i];
49         rep(i, 1, n-1){
50             cin >> u >> v;
51             G[u].push_back(v);
52             G[v].push_back(u);
53         }
54         ans = -INFF;
55         mem(dp, 0);
56         dfs(1, -1);
57         if(ans == -INFF) cout << "Impossible" << endl;
58         else    cout << ans << endl;
59     }
60     return 0;
61 }
View Code
相關文章
相關標籤/搜索