Official

E - Skiing Editorial by en_translator


First, by regarding the happiness multiplied by \(-1\) as the cost, the problem can be rephrased as a shortest path problem.

  • A graph with \(N\) vertices and \(2M\) edges is given.
  • Each vertex has the value of altitude \(H_i\) attributed to the vertex.
  • For each \(1\leq i\leq M\), let \(X_i\) and \(Y_i\) be the higher and the lower of the altitudes of \((U_i,V_i)\), respectively, then there is an edge from Vertex \(X_i\) to Vertex \(Y_i\) with cost \((H_{Y_i}-H_{X_i}) (\leq 0)\), and an edge from Vertex \(Y_i\) to Vertex \(X_i\) with cost \(2(H_{X_i}-H_{Y_i}) (\geq0)\).
  • (One can travel from any vertex to any vertex using edges)
  • Find the minimum cost (that may be negative) to reach the vertex that minimizes the cost. (= Find the minimum cost from Vertex \(1\) to each vertex, and find the minimum value of all of them.)

We cannot directly apply Dijkstra’s method, since this graph has edges with negative costs. On the other hand, Bellman-Ford algorithm costs \(O(NM)\) time, which is too slow. Instead, we will consider transforming this problem using the idea of potential, so that it can be solved with Dijkstra’s algorithm.

Specifically, consider the value of Takahashi’s (happiness) + (the altitude he is currently at). If we can find, for each space, the maximum of that value when he stops moving at that space, then we can determine the answer by finding for each space that value subtracted by the altitude of the space, and then finding their maximum value. By regarding (happiness)+(the altitude he is currently at) multiplied by \(-1\) as the cost, the problem can be rephrased as follows.

  • A graph with \(N\) vertices and \(2M\) edges is given.
  • Each vertex has the value of altitude \(H_i\) attributed to the vertex.
  • For each \(1\leq i\leq M\), let \(X_i\) and \(Y_i\) be the higher and the lower of the altitudes of \((U_i,V_i)\), respectively, then there is an edge from Vertex \(X_i\) to Vertex \(Y_i\) with cost \(0\), and an edge from Vertex \(Y_i\) to Vertex \(X_i\) with cost \((H_{X_i}-H_{Y_i}) (\geq0)\).
  • (One can travel from any vertex to any vertex using edges)
  • For each vertex, find the minimum cost from Vertex \(1\) to the vertex plus the altitude of the vertex \(H_i\), and find the minimum value of all of them.

This problem can be solved by finding the shortest path from Vertex \(1\) to each vertex and finding the max of the cost plus \(H_i\). Therefore, the problem has been solved in a total of \(O(N\log M)\) time.

Sample code in c++:

#include <bits/stdc++.h>
using namespace std;

#define N 200010
#define INF (long long)2e+18

using namespace std;

int main(void) {
	int n, m;
	long long h[N];
	vector<pair<int, long long> >e[N];

	priority_queue<pair<long long, int> >pq;
	pair<long long, int> p;
	long long d[N];

	int k, x, y;
	long long ans;

	cin >> n >> m;
	for (int i = 0; i < n; i++)cin >> h[i];
	for (int i = 0; i < m; i++) {
		cin >> x >> y;
		x--;
		y--;
		e[x].push_back({ y,max(h[y] - h[x],(long long)0) });
		e[y].push_back({ x,max(h[x] - h[y],(long long)0) });
	}

	for (int i = 0; i < n; i++)d[i] = INF;
	d[0] = 0;
	ans = 0;
	pq.push({ -d[0],0 });

	for (int i = 0; i < n; i++) {
			p = pq.top();
		while (d[p.second] < -p.first) {
				pq.pop();
				p = pq.top();
		}
		pq.pop();
		k = p.second;
		ans = max(ans, h[0] - h[k] - d[k]);
		for (int i = 0; i < e[k].size(); i++) {
			if (d[e[k][i].first] > (d[k] + e[k][i].second)) {
				d[e[k][i].first] = d[k] + e[k][i].second;
				pq.push({ -d[e[k][i].first],e[k][i].first });
			}
		}
	}

	cout << ans << endl;
	return 0;
}

posted:
last update: