Balkan OI 2017 - City Attractions
Author: Andi Qu
Introduction
Let the node that Gigel goes to from node be . Since the graph made from the directed edges is a functional graph, we can use binary jumping or any other efficient method to find the final node.
Now we only need to find all and we are done! However, this isn't as straightforward as it sounds...
A simpler problem
Let's consider a simpler problem: suppose we root the tree at node and Gigel can only move down the tree (don't worry about the leaves). In this problem, we can find all (and ) using a simple tree DP:
Let be the node in the subtree of (excluding itself) such that is maximized. Additionally, we store this value in the DP array. We can find by taking the best of and over all children of .
This algorithm runs in time.
Finding all
Obviously, the solution to the simpler problem doesn't solve the general problem: we might need to move up into a node's parent!
To address this issue, we can first do a DFS to find as defined above, and then do a second DFS to allow moving to a node's parent. See the solving for all roots module if you're unfamiliar with this technique. Essentially, we find the best destination from if we move up into 's parent and then compare that with .
After doing this, is simply as desired.
These two DFSes run in time, so the final complexity is (from the binary jumping).
Implementation
#include <bits/stdc++.h>typedef long long ll;using namespace std;int a[300001], nxt[2][300001];pair<int, int> dp[300001], pdp[300001];vector<int> graph[300001];void dfs1(int node = 1, int parent = 0) {dp[node] = {INT_MAX / 2, 0};
Alternative Code (Ben)
const int MX = 3e5 + 5;int N;ll K;array<pi, 2> bes[MX]; // for each x,// get best two a[y]-d(x,y), possibly including x itselfvi adj[MX];int nex[MX], vis[MX];array<pi, 2> comb(array<pi, 2> a, array<pi, 2> b) {
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!