1 solutions
-
0thakuremon LV 4 @ 2024-11-06 18:25:56
From any node P, we can visit at max two child of node P. The reason is , when we step into the node P the node is visited once, then lets say we went to a child A and came back from the child so we visited the node P twice. Now we can just visit another child and can not come back to the node P again, otherwise P will be visited more than twice.
Another important thing to notice is that when we go to visit the first child of P and willing to come back to P again we have to make sure that coming back to P does not require to visit any node more than twice. So we have to go through a straight path until we reach into a leaf node and come back to the P in the same path. In other words we will chose to visit only one child of each node until we reach into a leaf and then come back to P again by visiting some node twice. This way we can visit \(min(K , height[child])\) nodes.
It can be shown that before entering the 2nd child of P it is always better to spend as many K (double visit) as possible. Because when we enter the 2nd child of P we can not go back to P again and the tree shrinks for us.
Now come to the DP solution
lets say dp[i][j] = answer for the subtree of node-j when we have i nodes that can be visited twice.
transition : \(dp[i][j] = max(dp[i][j] , min(mxh,i) + dp[i-mxh][e] + 1)\) , for all i from 0 to K and for all edge e of node-j
\(mxh\) = maximum height of all the child except the child e
complexity : \(O(N*K)\)
c++ code: thakuremon
#include<bits/stdc++.h> using namespace std; vector<int> g[200005]; int height[200005] , dp[101][200005]; int n,k; void dfs(int node,int par) { height[node] = 0; for(int e:g[node]) { if(e==par) continue; dfs(e,node); } int mx = 0; for(int e:g[node]) { if(e==par) continue; mx = max(mx , height[e]); } height[node] = mx+1; } void dpontree(int node,int par) { int mxh=0,mxh2=0; for(auto e:g[node]) { if(e==par) continue; if(height[e] >= mxh) { mxh2 = mxh; mxh = height[e]; } else if(height[e] > mxh2) mxh2 = height[e]; } for(auto e:g[node]) { if(e==par) continue; dpontree(e,node); } for(int i=0;i<=k;i++) { dp[i][node] = 1; for(auto e:g[node]) { if(e==par) continue; if(height[e] == mxh) { dp[i][node] = max(dp[i][node] , min(mxh2,i) + dp[max(0,i-mxh2)][e] + 1); } else { dp[i][node] = max(dp[i][node] , min(mxh,i) + dp[max(0,i-mxh)][e] + 1); } } } } int main() { cin >> n >> k; for(int i=0;i<n-1;i++) { int u,v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } dfs(1,0); dpontree(1,0); cout << dp[k][1] << endl; }
- 1
Information
- ID
- 1111
- Difficulty
- 8
- Category
- (None)
- Tags
- # Submissions
- 40
- Accepted
- 4
- Accepted Ratio
- 10%
- Uploaded By