# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
825719 | KoD | Cyberland (APIO23_cyberland) | C++17 | 0 ms | 0 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "cyberland.h"
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
namespace kod {
namespace util {
template <class F> class FixedPoint : private F {
constexpr FixedPoint(F&& f) noexcept : F(std::forward<F>(f)) {}
template <class G> friend constexpr decltype(auto) make_fixed(G&&) noexcept;
public:
template <class... Args> constexpr decltype(auto) operator()(Args&&... args) const noexcept {
return F::operator()(*this, std::forward<Args>(args)...);
}
};
template <class G> [[nodiscard]] constexpr decltype(auto) make_fixed(G&& g) noexcept {
using F = std::decay_t<G>;
return FixedPoint<F>(std::forward<F>(g));
}
} // namespace util
} // namespace kod
namespace kod {
namespace util {
class ForwardLoop {
int x, y;
constexpr ForwardLoop(int x, int y) noexcept : x(x), y(y) {}
friend constexpr ForwardLoop rep(int, int) noexcept;
friend constexpr ForwardLoop rep(int) noexcept;
public:
constexpr ForwardLoop begin() const noexcept { return *this; }
constexpr std::monostate end() const noexcept { return {}; }
constexpr bool operator!=(std::monostate) const noexcept { return x < y; }
constexpr void operator++() const noexcept {}
constexpr int operator*() noexcept { return x++; }
};
[[nodiscard]] constexpr ForwardLoop rep(int l, int r) noexcept { return ForwardLoop(l, r); }
[[nodiscard]] constexpr ForwardLoop rep(int n) noexcept { return ForwardLoop(0, n); }
class BackwardLoop {
int x, y;
constexpr BackwardLoop(int x, int y) noexcept : x(x), y(y) {}
friend constexpr BackwardLoop revrep(int, int) noexcept;
friend constexpr BackwardLoop revrep(int) noexcept;
public:
constexpr BackwardLoop begin() const noexcept { return *this; }
constexpr std::monostate end() const noexcept { return {}; }
constexpr bool operator!=(std::monostate) const noexcept { return x > y; }
constexpr void operator++() const noexcept {}
constexpr int operator*() noexcept { return --x; }
};
[[nodiscard]] constexpr BackwardLoop revrep(int l, int r) noexcept { return BackwardLoop(r, l); }
[[nodiscard]] constexpr BackwardLoop revrep(int n) noexcept { return BackwardLoop(n, 0); }
template <class F> constexpr void repeat(int n, const F& f) noexcept {
assert(n >= 0);
while (n--) f();
}
} // namespace util
} // namespace kod
namespace kod {
namespace sol {
using ll = long long;
using uint = unsigned;
using ull = unsigned long long;
using std::array;
using std::pair;
using std::string;
using std::tuple;
using std::vector;
using namespace util;
constexpr int inf = std::numeric_limits<int>::max() / 2;
constexpr ll infll = std::numeric_limits<ll>::max() / 2;
constexpr ll floor_div(ll x, ll y) noexcept {
assert(y != 0);
return x / y - ((x ^ y) < 0 && x % y != 0);
}
constexpr ll ceil_div(ll x, ll y) noexcept {
assert(y != 0);
return x / y + ((x ^ y) >= 0 && x % y != 0);
}
template <class T> constexpr bool setmin(T& lhs, const T& rhs) noexcept {
if (lhs > rhs) {
lhs = rhs;
return true;
}
return false;
}
template <class T> constexpr bool setmax(T& lhs, const T& rhs) noexcept {
if (lhs < rhs) {
lhs = rhs;
return true;
}
return false;
}
} // namespace sol
} // namespace kod
#ifdef KOD_LOCAL
#define OJ_LOCAL(a, b) b
#include <kodlib/misc/debug>
#else
#define OJ_LOCAL(a, b) a
#define DBG(...)
#define SHOW(...)
#endif
constexpr int T = 67;
std::array<double, T> dist[100000];
template <class T> class SimpleQueue {
std::vector<T> payload;
int pos;
public:
SimpleQueue() : payload(), pos(0) {}
explicit SimpleQueue(const int n) : SimpleQueue() { reserve(n); }
int size() const { return (int)payload.size() - pos; }
bool empty() const { return size() == 0; }
T& front() { return payload[pos]; }
void push(const T& t) { payload.push_back(t); }
void push(T&& t) { payload.push_back(std::move(t)); }
void pop() { pos++; }
void reserve(int n) { payload.reserve(n); }
void clear() {
payload.clear();
pos = 0;
}
};
double solve(int N,
int M,
int K,
int H,
std::vector<int> X,
std::vector<int> Y,
std::vector<int> C,
std::vector<int> A) {
using namespace kod::sol;
vector<int> deg(N + 1);
for (const int i : rep(M)) {
deg[X[i]] += 1;
deg[Y[i]] += 1;
}
for (const int i : rep(N)) {
deg[i + 1] += deg[i];
}
vector<int> graph(2 * M);
for (const int i : rep(M)) {
graph[--deg[X[i]]] = i;
graph[--deg[Y[i]]] = i;
}
vector<char> reach(N);
{
SimpleQueue<int> que(N);
const auto push = [&](int u) {
if (!reach[u]) {
reach[u] = true;
que.push(u);
}
};
push(0);
while (!que.empty()) {
const int u = que.front();
que.pop();
if (u == H) continue;
for (const int i : rep(deg[u], deg[u + 1])) {
const int e = graph[i];
const int v = X[e] ^ Y[e] ^ u;
push(v);
}
}
}
if (!reach[H]) {
return -1;
}
for (const int i : rep(N)) {
dist[i].fill(infll);
}
struct info {
int u, k;
double d;
bool operator<(const info& t) const { return d > t.d; }
};
std::priority_queue<info> heap;
const auto push = [&](int u, int k, double d) {
if (k < std::min(K + 1, T) && setmin(dist[u][k], d)) {
heap.push({u, k, d});
}
};
push(0, 0, 0);
for (const int i : rep(N)) {
if (reach[i] && A[i] == 0) {
push(i, 0, 0);
}
}
while (!heap.empty()) {
const auto [u, k, d] = heap.top();
heap.pop();
if (u == H) continue;
if (d > dist[u][k] + 1e-9) continue;
for (const int i : rep(deg[u], deg[u + 1])) {
const int e = graph[i];
const int v = X[e] ^ Y[e] ^ u;
push(v, k, d + C[e]);
if (A[v] == 2) {
push(v, k + 1, (d + C[e]) / 2);
}
}
}
return *std::min_element(dist[H].begin(), dist[H].end());
}
#include <vector>
double solve(int N, int M, int K, int H, std::vector<int> x, std::vector<int> y, std::vector<int> c, std::vector<int> arr);
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
namespace kod {
namespace util {
template <class F> class FixedPoint : private F {
constexpr FixedPoint(F&& f) noexcept : F(std::forward<F>(f)) {}
template <class G> friend constexpr decltype(auto) make_fixed(G&&) noexcept;
public:
template <class... Args> constexpr decltype(auto) operator()(Args&&... args) const noexcept {
return F::operator()(*this, std::forward<Args>(args)...);
}
};
template <class G> [[nodiscard]] constexpr decltype(auto) make_fixed(G&& g) noexcept {
using F = std::decay_t<G>;
return FixedPoint<F>(std::forward<F>(g));
}
} // namespace util
} // namespace kod
namespace kod {
namespace util {
class ForwardLoop {
int x, y;
constexpr ForwardLoop(int x, int y) noexcept : x(x), y(y) {}
friend constexpr ForwardLoop rep(int, int) noexcept;
friend constexpr ForwardLoop rep(int) noexcept;
public:
constexpr ForwardLoop begin() const noexcept { return *this; }
constexpr std::monostate end() const noexcept { return {}; }
constexpr bool operator!=(std::monostate) const noexcept { return x < y; }
constexpr void operator++() const noexcept {}
constexpr int operator*() noexcept { return x++; }
};
[[nodiscard]] constexpr ForwardLoop rep(int l, int r) noexcept { return ForwardLoop(l, r); }
[[nodiscard]] constexpr ForwardLoop rep(int n) noexcept { return ForwardLoop(0, n); }
class BackwardLoop {
int x, y;
constexpr BackwardLoop(int x, int y) noexcept : x(x), y(y) {}
friend constexpr BackwardLoop revrep(int, int) noexcept;
friend constexpr BackwardLoop revrep(int) noexcept;
public:
constexpr BackwardLoop begin() const noexcept { return *this; }
constexpr std::monostate end() const noexcept { return {}; }
constexpr bool operator!=(std::monostate) const noexcept { return x > y; }
constexpr void operator++() const noexcept {}
constexpr int operator*() noexcept { return --x; }
};
[[nodiscard]] constexpr BackwardLoop revrep(int l, int r) noexcept { return BackwardLoop(r, l); }
[[nodiscard]] constexpr BackwardLoop revrep(int n) noexcept { return BackwardLoop(n, 0); }
template <class F> constexpr void repeat(int n, const F& f) noexcept {
assert(n >= 0);
while (n--) f();
}
} // namespace util
} // namespace kod
namespace kod {
namespace sol {
using ll = long long;
using uint = unsigned;
using ull = unsigned long long;
using std::array;
using std::pair;
using std::string;
using std::tuple;
using std::vector;
using namespace util;
constexpr int inf = std::numeric_limits<int>::max() / 2;
constexpr ll infll = std::numeric_limits<ll>::max() / 2;
constexpr ll floor_div(ll x, ll y) noexcept {
assert(y != 0);
return x / y - ((x ^ y) < 0 && x % y != 0);
}
constexpr ll ceil_div(ll x, ll y) noexcept {
assert(y != 0);
return x / y + ((x ^ y) >= 0 && x % y != 0);
}
template <class T> constexpr bool setmin(T& lhs, const T& rhs) noexcept {
if (lhs > rhs) {
lhs = rhs;
return true;
}
return false;
}
template <class T> constexpr bool setmax(T& lhs, const T& rhs) noexcept {
if (lhs < rhs) {
lhs = rhs;
return true;
}
return false;
}
} // namespace sol
} // namespace kod
#ifdef KOD_LOCAL
#define OJ_LOCAL(a, b) b
#include <kodlib/misc/debug>
#else
#define OJ_LOCAL(a, b) a
#define DBG(...)
#define SHOW(...)
#endif
double solve(int N, int M, int K, int H, std::vector<int> X, std::vector<int> Y, std::vector<int> C, std::vector<int> A) {
using namespace kod::sol;
vector<vector<int>> graph(N);
for (const int i : rep(M)) {
graph[X[i]].push_back(i);
graph[Y[i]].push_back(i);
}
vector<char> reach(N);
{
std::queue<int> que;
const auto push = [&](int u) {
if (!reach[u]) {
reach[u] = true;
que.push(u);
}
};
push(0);
while (!que.empty()) {
const int u = que.front();
que.pop();
if (u == H) continue;
for (const int e : graph[u]) {
const int v = X[e] ^ Y[e] ^ u;
push(v);
}
}
}
if (!reach[H]) {
return -1;
}
constexpr int T = 70;
vector<array<double, T>> dist(N);
for (auto& a : dist) a.fill(infll);
struct info {
int u, k;
double d;
bool operator<(const info& t) const { return d > t.d; }
};
std::priority_queue<info> heap;
const auto push = [&](int u, int k, double d) {
if (k < std::min(K + 1, T) && setmin(dist[u][k], d)) {
heap.push({u, k, d});
}
};
push(0, 0, 0);
for (const int i : rep(N)) {
if (reach[i] && A[i] == 0) {
push(i, 0, 0);
}
}
while (!heap.empty()) {
const auto [u, k, d] = heap.top();
heap.pop();
if (u == H) continue;
if (d > dist[u][k] + 1e-6) continue;
for (const int e : graph[u]) {
const int v = X[e] ^ Y[e] ^ u;
push(v, k, d + C[e]);
if (A[v] == 2) {
push(v, k + 1, (d + C[e]) / 2);
}
}
}
return *std::min_element(dist[H].begin(), dist[H].end());
}