Submission #1247545

#TimeUsernameProblemLanguageResultExecution timeMemory
1247545MateiKing80Chase (CEOI17_chase)C++20
0 / 100
400 ms173576 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; #define int ll #define jos 0 #define sus 1 const int N = 1e5 + 5, V = 105, inf = 1e16; int dp[2][V][N], p[N], v, ans; vector<int> vec[N]; void dfs(int nod, int papa) { for (auto i : vec[nod]) if (i != papa) dfs(i, nod); int sumvec = 0; for (auto i : vec[nod]) if (i != papa) sumvec += p[i]; dp[jos][1][nod] = sumvec + p[papa]; dp[sus][1][nod] = sumvec + p[papa]; for (int i = 0; i <= v; i ++) { dp[sus][i][nod] = max(dp[sus][i][nod], dp[sus][i - 1][papa] + sumvec); dp[sus][i][nod] = max(dp[sus][i][nod], dp[sus][i][papa]); } for (auto i : vec[nod]) { if (i == papa) continue; for (int j = 0; j <= v; j ++) { dp[jos][j][nod] = max(dp[jos][j][nod], dp[jos][j][i]); if (j) dp[jos][j][nod] = max(dp[jos][j][nod], dp[jos][j - 1][i] + sumvec - p[i] + p[papa]); } } //nu punem in nod -> max(dp[jos][i][x] + dp[sus][v - i][y]; x != y DIFERITE (sa nu vina din acelasi loc vector<vector<int>> vsus(2, vector<int> (v + 1)); for (auto i : vec[nod]) { if (i == papa) continue; for (int j = 0; j <= v; j ++) { if (dp[sus][j][i] > vsus[0][j]) { vsus[1][j] = vsus[0][j]; vsus[0][j] = dp[sus][j][i]; } else if (dp[sus][j][i] > vsus[1][j]) { vsus[1][j] = dp[sus][j][i]; } } } for (auto i : vec[nod]) { if (i == papa) continue; for (int j = 0; j <= v; j ++) ans = max(ans, dp[jos][j][i] + (dp[sus][v - j][i] == vsus[0][v - j] ? vsus[1][v - j] : vsus[0][v - j])); for (int j = 0; j < v; j ++) ans = max(ans, dp[jos][j][i] + sumvec + p[papa] - p[i] + (dp[sus][v - j - 1][i] == vsus[0][v - j - 1] ? vsus[1][v - j - 1] : vsus[0][v - j - 1])); } //punem in nod -> max(dp[jos][i][x] + dp[sus][v - i - 1][y] + sumvec[nod] + p[papa] - p[x]) //incepem si terminam in nod if (v) ans = max(ans, sumvec); //incepem in nod ans = max(ans, vsus[0][v]); for (auto i : vec[nod]) if (i != papa && v) ans = max(ans, dp[sus][v - 1][i] + sumvec + p[papa]); //terminam in nod for (auto i : vec[nod]) if (i != papa) { if (v) ans = max(ans, dp[jos][v - 1][i] + sumvec + p[papa] - p[i]); ans = max(ans, dp[jos][v][i]); } for (int i = 1; i <= v; i ++) { dp[jos][i][nod] = max(dp[jos][i][nod], dp[jos][i - 1][nod]); dp[sus][i][nod] = max(dp[sus][i][nod], dp[sus][i - 1][nod]); } /* acum partea in care chiar calculez raspunsul trebuie unite astea adica trebe sa vina sus de undeva si jos de altundeva SAU incepe / se termina in nod */ } /* dp[jos] va fi calculat cu toti vecinii si dupa va trebui sa scoatem ala in care ne ducem */ signed main() { int n; cin >> n >> v; for (int i = 1; i <= n; i ++) cin >> p[i]; for (int i = 0; i <= n; i ++) for (int j = 1; j <= v; j ++) dp[jos][j][i] = dp[sus][j][i] = -inf; dp[sus][0][0] = dp[jos][0][0] = -inf; for (int i = 1; i < n; i ++) { int x, y; cin >> x >> y; vec[x].push_back(y); vec[y].push_back(x); } dfs(1, 0); cout << ans << '\n'; } /* poti zice dp[sus/jos][paine][nod]; practic eu adun toti vecinii prin care nu am trecut inainte este clar ca vreau sa arunc paine la primu nod prin care trec */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...