给出每个顶点的happy值,还有若干组两个顶点L,K关系,表示K是L的上司。求当K、L不同时出现时获得的happy值的最大和。
设dp[u][0]表示不选u结点时获得的最大值,dp[u][1]表示选u结点时获得的最大值。则有:
dp[u][0]+=max(dp[v][0],dp[v][1]),dp[u][1]+=dp[v][0](u为v的父节点)
当父亲节点用有向边连向子节点时,会形成一颗树,自然就只有一个根。那么从根开始dfs就行了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<algorithm> 6 using namespace std; 7 const int maxn = 6200; 8 int dp[maxn][2], vis[maxn], a[maxn]; 9 vector<int> tree[maxn]; 10 int N; 11 12 void Init() 13 { 14 for (int i = 1; i <= N; i++) { 15 cin >> a[i]; 16 tree[i].clear(), vis[i] = 0; 17 } 18 int L, K; 19 while (cin>>L>>K) 20 { 21 if (L == 0 && K == 0) break; 22 tree[K].push_back(L); 23 vis[L] = 1; 24 } 25 tree[0].clear();//找根 26 for(int i=1;i<=N;i++) 27 if (!vis[i]) { 28 tree[0].push_back(i); 29 break;//只有一个根,找到后就break 30 } 31 } 32 33 void dfs(int u) 34 { 35 dp[u][0] = 0; 36 dp[u][1] = a[u]; 37 for (int i = 0; i < tree[u].size(); i++) 38 { 39 int v = tree[u][i]; 40 dfs(v); 41 dp[u][0] += max(dp[v][0], dp[v][1]); 42 dp[u][1] += dp[v][0]; 43 } 44 } 45 46 void Solve() 47 { 48 int root = tree[0][0]; 49 dfs(root); 50 cout << max(dp[root][0], dp[root][1]) << endl; 51 } 52 53 int main() 54 { 55 while (cin>>N) 56 { 57 Init(); 58 Solve(); 59 } 60 return 0; 61 }
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<vector> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 const int maxn=6200; 9 int dp[maxn][2],rat[maxn],f[maxn],vis[maxn]; 10 vector<int> tree[maxn]; 11 12 void dfs(int u) 13 { 14 vis[u]=1; 15 dp[u][0]=0; 16 dp[u][1]=rat[u]; 17 int len=tree[u].size(); 18 for(int i=0;i<len;i++){ 19 int v=tree[u][i]; 20 if(vis[v]) continue; 21 dfs(v); 22 dp[u][0]+=max(dp[v] [1],dp[v][0]); 23 dp[u][1]+=dp[v][0]; 24 } 25 } 26 27 int main() 28 { 29 int N; 30 while(scanf("%d",&N)==1) 31 { 32 for(int i=1;i<=N;i++){ 33 scanf("%d",&rat[i]); 34 vis[i]=0;f[i]=-1; 35 tree[i].clear(); 36 } 37 int a,b; 38 while(scanf("%d%d",&a,&b)) 39 { 40 if(a==0&&b==0) break; 41 f[a]=b; 42 tree[b].push_back(a); 43 } 44 int root; 45 for(int i=1;i<=N;i++){ 46 if(f[i]==-1){ 47 root=i; 48 break; 49 } 50 } 51 dfs(root); 52 cout<<max(dp[root][0],dp[root][1])<<endl; 53 } 54 return 0; 55 }