結果
| 問題 |
No.1069 電柱 / Pole (Hard)
|
| コンテスト | |
| ユーザー |
risujiroh
|
| 提出日時 | 2020-05-29 23:43:34 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 470 ms / 2,000 ms |
| コード長 | 3,956 bytes |
| コンパイル時間 | 3,276 ms |
| コンパイル使用メモリ | 231,444 KB |
| 最終ジャッジ日時 | 2025-01-10 18:30:55 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 79 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include "debug.h"
#else
#define DEBUG(...)
#endif
template <class T> struct graph {
struct edge {
int to;
T w;
operator int() const { return to; }
};
template <class It> struct edge_list {
const It bg, ed;
It begin() const { return bg; }
It end() const { return ed; }
auto&& operator[](size_t i) const { return bg[i]; }
size_t size() const { return ed - bg; }
};
vector<pair<int, edge>> pool;
vector<int> head;
vector<edge> edges;
graph(int n) : head(n + 1) {}
void add(int from, int to, T w = 1) {
pool.push_back({from, {to, w}});
++head[from];
}
void build() {
partial_sum(begin(head), end(head), begin(head));
edges.resize(head.back());
while (not empty(pool)) {
edges[--head[pool.back().first]] = pool.back().second;
pool.pop_back();
}
decltype(pool)().swap(pool);
}
edge_list<class vector<edge>::const_iterator> operator[](int v) const {
return {begin(edges) + head[v], begin(edges) + head[v + 1]};
}
edge_list<class vector<edge>::iterator> operator[](int v) {
return {begin(edges) + head[v], begin(edges) + head[v + 1]};
}
size_t size() const { return std::size(head) - 1; }
};
template <class T> constexpr T inf = numeric_limits<T>::max() / 2.1;
auto chmin = [](auto&& a, auto b) { return b < a ? a = b, 1 : 0; };
template <class T, class G> auto dijkstra(const G& g, int s, int t) {
vector d(size(g), inf<T>);
vector prv(size(g), -1);
priority_queue<pair<T, int>, vector<pair<T, int>>, greater<>> rh;
rh.emplace(d[s] = 0, s);
while (not empty(rh)) {
auto [dv, v] = rh.top();
rh.pop();
if (dv != d[v]) continue;
for (auto&& e : g[v])
if (chmin(d[e.to], dv + e.w)) {
rh.emplace(d[e.to], e.to);
prv[e.to] = v;
}
}
vector<int> vs;
for (int v = t; v != -1; v = prv[v]) {
vs.push_back(v);
if (v == s) break;
}
reverse(begin(vs), end(vs));
return make_pair(d[t], vs);
}
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
cout << fixed << setprecision(20);
int n, m, k, s, t;
cin >> n >> m >> k >> s >> t;
--s, --t;
vector<double> x(n), y(n);
for (int i = 0; i < n; ++i) {
cin >> x[i] >> y[i];
}
graph<double> g(n);
while (m--) {
int u, v;
cin >> u >> v;
--u, --v;
double w = hypot(x[v] - x[u], y[v] - y[u]);
g.add(u, v, w);
g.add(v, u, w);
}
g.build();
set<pair<double, vector<int>>> se;
se.insert(dijkstra<double>(g, s, t));
vector<vector<int>> ps;
while (k--) {
if (empty(se)) {
cout << "-1\n";
continue;
}
cout << begin(se)->first << '\n';
auto vs = begin(se)->second;
ps.push_back(vs);
se.erase(begin(se));
double cur = 0;
for (int i = 0; i < (int)size(vs) - 1; ++i) {
int v = vs[i];
vector<map<int, double>> mp(n);
for (auto&& p : ps) {
if (i < (int)size(p) and vector(begin(p), begin(p) + (i + 1)) == vector(begin(vs), begin(vs) + (i + 1))) {
for (auto&& e : g[v]) {
if (e == p[i + 1] and e.w != inf<double>) {
mp[v][e] = exchange(e.w, inf<double>);
}
}
}
}
for (int j = 0; j < i; ++j) {
for (auto&& e : g[vs[j]]) {
mp[vs[j]][e] = exchange(e.w, inf<double>);
}
}
auto p = dijkstra<double>(g, v, t);
if (p.first < inf<double>) {
vector nvs(begin(vs), begin(vs) + i);
nvs.insert(end(nvs), begin(p.second), end(p.second));
se.emplace(cur + p.first, nvs);
}
for (int j = 0; j < i; ++j) {
for (auto&& e : g[vs[j]]) {
if (e.w == inf<double>) {
e.w = mp[vs[j]][e];
}
}
}
for (auto&& e : g[v]) {
if (mp[v].count(e)) {
e.w = mp[v][e];
}
if (e == vs[i + 1]) {
cur += e.w;
}
}
}
}
}
risujiroh