Submission #1281688

#TimeUsernameProblemLanguageResultExecution timeMemory
1281688hxianHard route (IZhO17_road)C++20
100 / 100
489 ms121256 KiB
// dmoj problem: https://vjudge.net/contest/757167#problem/K #include <bits/stdc++.h> #define int long long #define MOD 1000000007 using namespace std; int n, out, amnt; pair<int, int> dist[500001]; vector<int> adjList[500001]; void dfs(int node, int last) { dist[node] = {0, 1}; for (int u : adjList[node]) { if (u != last) { dfs(u, node); if (dist[u].first + 1 > dist[node].first) dist[node] = {dist[u].first + 1, dist[u].second}; else if (dist[u].first + 1 == dist[node].first) dist[node].second += dist[u].second; } } } void reroot(int node, int last, int before, int waysbefore) { vector<pair<int, int>> options; if (before != 0) options.push_back({before, waysbefore}); for (int u : adjList[node]) if (u != last) options.push_back({dist[u].first + 1, dist[u].second}); sort(options.begin(), options.end()); if (options.size() == 1) { if (out == 0) amnt += waysbefore; // this will overcount x2 } if (options.size() == 2) { } // overcount if (options.size() >= 3) { int candout = options[options.size() - 1].first * (options[options.size() - 2].first + options[options.size() - 3].first); if (candout > out) { out = candout; amnt = 0; } if (candout == out) { pair<int, int> want = {-1, -1}; want.first = options[options.size() - 2].first; if (options[options.size() - 3].first != want.first) want.second = options[options.size() - 3].first; pair<int, int> sums; int delta = 0; for (int i = 0; i < options.size(); i++) { if (options[i].first == want.first) sums.first += options[i].second; if (options[i].first == want.second) sums.second += options[i].second; } if (want.second != -1) delta += sums.first * sums.second; else { delta += sums.first * sums.first; for (int i = 0; i < options.size(); i++) if (options[i].first == want.first) delta -= options[i].second * options[i].second; delta /= 2; } amnt += delta; } } int amntbest = 0; int sb = -1; int amntsecondbest = 0; for (int i = options.size() - 1; i >= 0; i--) { if (options[i].first == options.back().first) amntbest += options[i].second; else if (sb == -1) sb = options[i].first; if (options[i].first == sb) amntsecondbest += options[i].second; } for (int u : adjList[node]) if (u != last) { if (dist[u].first + 1 == options.back().first) { if (amntbest - dist[u].second > 0) reroot(u, node, options.back().first + 1, amntbest - dist[u].second); else reroot(u, node, sb + 1, amntsecondbest); } else reroot(u, node, options.back().first + 1, amntbest); } } int32_t main() { cin.sync_with_stdio(0); cin.tie(0); cin >> n; for (int i = 0; i < n - 1; i++) { int a, b; cin >> a >> b; adjList[a].push_back(b); adjList[b].push_back(a); } if (n == 2) { cout << "0 1" << "\n"; return 0; } for (int i = 1; i <= n; i++) { if (adjList[i].size() != 1) { dfs(i, 0); reroot(i, 0, 0, 1); break; } } cout << out << " "; cout << (out == 0 ? amnt / 2 : amnt) << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...