AOJ 0562 Shopping in JOI Kingdom
解法
まず,各頂点がショッピングモールからどれだけ離れているかを求める.
これは,ショッピングモールの頂点をあらかじめ全てpriority_queueに突っ込んでおいたダイクストラを解けばよい.
すると解の候補としては
- 求めた各頂点のショッピングモールからの距離
- 隣接した2頂点の,それぞれのショッピングモールからの距離d1, d2と,2頂点を結ぶ辺の重みを足したものを2で割ったもの
の2つであるから,これらを実際に求めれば良い.
出力する答えを四捨五入するのを忘れずに.
計算量は O(MlogN + N + M).
ソースコード
#include <bits/stdc++.h> using namespace std; using P = pair<int, int>; struct edge { int to, weight; }; constexpr int INF = 1e9; int main() { int N, M, K; cin >> N >> M >> K; vector<vector<edge>> g(N); for(int i=0; i<M; ++i) { int a, b, l; cin >> a >> b >> l; a--; b--; g[a].push_back((edge){b, l}); g[b].push_back((edge){a, l}); } priority_queue<P, vector<P>, greater<P>> que; vector<int> d(N, INF); for(int i=0; i<K; ++i) { int s; cin >> s; s--; que.push(make_pair(0, s)); d[s] = 0; } while(!que.empty()) { P p = que.top(); que.pop(); int v = p.second; if(d[v] < p.first) { continue; } for(auto& e : g[v]) { if(d[e.to] > d[v] + e.weight) { d[e.to] = d[v] + e.weight; que.push(make_pair(d[e.to], e.to)); } } } double res = 0; for(int i=0; i<N; ++i) { res = max(res, (double)d[i]); for(int j=0; j<g[i].size(); ++j) { res = max(res, (d[i] + d[g[i][j].to] + g[i][j].weight) / 2.0); } } cout << (int)floor(res + 0.5) << endl; }