結果
| 問題 |
No.1283 Extra Fee
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-11-30 22:08:36 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 205 ms / 2,000 ms |
| コード長 | 15,903 bytes |
| コンパイル時間 | 3,520 ms |
| コンパイル使用メモリ | 320,368 KB |
| 最終ジャッジ日時 | 2025-01-16 10:32:50 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 30 |
ソースコード
/**
* date : 2020-11-30 22:08:30
*/
#define NDEBUG
#include <immintrin.h>
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2945"
//
using namespace std;
// intrinstic
#include <immintrin.h>
// bits
#include <bits/stdc++.h>
// utility
namespace Nyaan {
using ll = long long;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
template <typename T>
using V = vector<T>;
template <typename T>
using VV = vector<vector<T>>;
using vi = vector<int>;
using vl = vector<long long>;
using vd = V<double>;
using vs = V<string>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<long long>>;
template <typename T, typename U>
struct P : pair<T, U> {
template <typename... Args>
P(Args... args) : pair<T, U>(args...) {}
using pair<T, U>::first;
using pair<T, U>::second;
T &x() { return first; }
const T &x() const { return first; }
U &y() { return second; }
const U &y() const { return second; }
P &operator+=(const P &r) {
first += r.first;
second += r.second;
return *this;
}
P &operator-=(const P &r) {
first -= r.first;
second -= r.second;
return *this;
}
P &operator*=(const P &r) {
first *= r.first;
second *= r.second;
return *this;
}
P operator+(const P &r) const { return P(*this) += r; }
P operator-(const P &r) const { return P(*this) -= r; }
P operator*(const P &r) const { return P(*this) *= r; }
};
using pl = P<ll, ll>;
using pi = P<int, int>;
using vp = V<pl>;
constexpr int inf = 1001001001;
constexpr long long infLL = 4004004004004004004LL;
template <typename T>
int sz(const T &t) {
return t.size();
}
template <typename T, size_t N>
void mem(T (&a)[N], int c) {
memset(a, c, sizeof(T) * N);
}
template <typename T, typename U>
inline bool amin(T &x, U y) {
return (y < x) ? (x = y, true) : false;
}
template <typename T, typename U>
inline bool amax(T &x, U y) {
return (x < y) ? (x = y, true) : false;
}
template <typename T>
int lb(const vector<T> &v, const T &a) {
return lower_bound(begin(v), end(v), a) - begin(v);
}
template <typename T>
int ub(const vector<T> &v, const T &a) {
return upper_bound(begin(v), end(v), a) - begin(v);
}
template <typename T>
int btw(T a, T x, T b) {
return a <= x && x < b;
}
template <typename T, typename U>
T ceil(T a, U b) {
return (a + b - 1) / b;
}
constexpr long long TEN(int n) {
long long ret = 1, x = 10;
for (; n; x *= x, n >>= 1) ret *= (n & 1 ? x : 1);
return ret;
}
template <typename T, typename U>
pair<T, U> mkp(const T &t, const U &u) {
return make_pair(t, u);
}
template <typename T>
vector<T> mkrui(const vector<T> &v, bool rev = false) {
vector<T> ret(v.size() + 1);
if (rev) {
for (int i = int(v.size()) - 1; i >= 0; i--) ret[i] = v[i] + ret[i + 1];
} else {
for (int i = 0; i < int(v.size()); i++) ret[i + 1] = ret[i] + v[i];
}
return ret;
};
template <typename T>
vector<T> mkuni(const vector<T> &v) {
vector<T> ret(v);
sort(ret.begin(), ret.end());
ret.erase(unique(ret.begin(), ret.end()), ret.end());
return ret;
}
template <typename F>
vector<int> mkord(int N, F f) {
vector<int> ord(N);
iota(begin(ord), end(ord), 0);
sort(begin(ord), end(ord), f);
return ord;
}
template <typename T>
vector<T> reord(const vector<T> &v, const vector<T> &ord) {
int N = v.size();
vector<T> ret(N);
for (int i = 0; i < N; i++) ret[i] = v[ord[i]];
return ret;
};
template <typename T = int>
vector<T> mkiota(int N) {
vector<T> ret(N);
iota(begin(ret), end(ret), 0);
return ret;
}
template <typename T>
vector<int> mkinv(vector<T> &v, int max_val = -1) {
if (max_val < (int)v.size()) max_val = v.size() - 1;
vector<int> inv(max_val + 1, -1);
for (int i = 0; i < (int)v.size(); i++) inv[v[i]] = i;
return inv;
}
} // namespace Nyaan
// bit operation
namespace Nyaan {
__attribute__((target("popcnt"))) inline int popcnt(const u64 &a) {
return _mm_popcnt_u64(a);
}
__attribute__((target("bmi"))) inline int botbit(const u64 &a) {
return _tzcnt_u64(a);
}
__attribute__((target("bmi"))) inline int ctz(const u64 &a) {
return _tzcnt_u64(a);
}
__attribute__((target("lzcnt"))) inline int topbit(const u64 &a) {
return 63 - _lzcnt_u64(a);
}
__attribute__((target("lzcnt"))) inline int clz64(const u64 &a) {
return _lzcnt_u64(a);
}
template <typename T>
inline int gbit(const T &a, int i) {
return (a >> i) & 1;
}
template <typename T>
inline void sbit(T &a, int i, bool b) {
a ^= (gbit(a, i) == b ? 0 : (T(b) << i));
}
constexpr long long PW(int n) { return 1LL << n; }
constexpr long long MSK(int n) { return (1LL << n) - 1; }
} // namespace Nyaan
// inout
namespace Nyaan {
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
os << p.first << " " << p.second;
return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
is >> p.first >> p.second;
return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
int s = (int)v.size();
for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
for (auto &x : v) is >> x;
return is;
}
void in() {}
template <typename T, class... U>
void in(T &t, U &... u) {
cin >> t;
in(u...);
}
void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &... u) {
cout << t;
if (sizeof...(u)) cout << sep;
out(u...);
}
void outr() {}
template <typename T, class... U, char sep = ' '>
void outr(const T &t, const U &... u) {
cout << t;
outr(u...);
}
struct IoSetupNya {
IoSetupNya() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
cout << fixed << setprecision(15);
cerr << fixed << setprecision(7);
}
} iosetupnya;
} // namespace Nyaan
// debug
namespace DebugImpl {
void dump(const char& t) { cerr << t; }
void dump(const string& t) { cerr << t; }
template <typename T>
void dump(const T& t, enable_if_t<is_integral<T>::value>* = nullptr) {
string res;
if (t == Nyaan::inf) res = "inf";
if (is_signed<T>::value)
if (t == -Nyaan::inf) res = "-inf";
if (sizeof(T) == 8) {
if (t == Nyaan::infLL) res = "inf";
if (is_signed<T>::value)
if (t == -Nyaan::infLL) res = "-inf";
}
if (res.empty()) res = to_string(t);
cerr << res;
}
template <typename T, typename U>
void dump(const pair<T, U>&);
template <typename T>
void dump(const pair<T*, int>&);
template <typename T>
void dump(const T& t,
enable_if_t<!is_void<typename T::iterator>::value>* = nullptr) {
cerr << "[ ";
for (auto it = t.begin(); it != t.end();) {
dump(*it);
cerr << (++it == t.end() ? " ]" : ", ");
}
}
template <typename T, typename U>
void dump(const pair<T, U>& t) {
cerr << "( ";
dump(t.first);
cerr << ", ";
dump(t.second);
cerr << " )";
}
template <typename T>
void dump(const pair<T*, int>& t) {
cerr << "[ ";
for (int i = 0; i < t.second; i++) {
dump(t.first[i]);
cerr << (i == t.second - 1 ? " ]" : ", ");
}
}
void trace() { cerr << endl; }
template <typename Head, typename... Tail>
void trace(Head&& head, Tail&&... tail) {
cerr << " ";
dump(head);
if (sizeof...(tail) != 0) cerr << ",";
trace(forward<Tail>(tail)...);
}
} // namespace DebugImpl
using DebugImpl::trace;
#ifdef NyaanDebug
#define trc(...) \
do { \
cerr << "## " << #__VA_ARGS__ << " = "; \
DebugImpl::trace(__VA_ARGS__); \
} while (0)
#else
#define trc(...)
#endif
// macro
#define each(x, v) for (auto&& x : v)
#define all(v) (v).begin(), (v).end()
#define rep(i, N) for (long long i = 0; i < (long long)(N); i++)
#define repr(i, N) for (long long i = (long long)(N)-1; i >= 0; i--)
#define rep1(i, N) for (long long i = 1; i <= (long long)(N); i++)
#define repr1(i, N) for (long long i = (N); (long long)(i) > 0; i--)
#define reg(i, a, b) for (long long i = (a); i < (b); i++)
#define regr(i, a, b) for (long long i = (b)-1; i >= (a); i--)
#define repc(i, a, cond) for (long long i = (a); (cond); i++)
#define ini(...) \
int __VA_ARGS__; \
in(__VA_ARGS__)
#define inl(...) \
long long __VA_ARGS__; \
in(__VA_ARGS__)
#define ins(...) \
string __VA_ARGS__; \
in(__VA_ARGS__)
#define inc(...) \
char __VA_ARGS__; \
in(__VA_ARGS__)
#define in2(s, t) \
for (int i = 0; i < (int)s.size(); i++) { \
in(s[i], t[i]); \
}
#define in3(s, t, u) \
for (int i = 0; i < (int)s.size(); i++) { \
in(s[i], t[i], u[i]); \
}
#define in4(s, t, u, v) \
for (int i = 0; i < (int)s.size(); i++) { \
in(s[i], t[i], u[i], v[i]); \
}
#define die(...) \
do { \
Nyaan::out(__VA_ARGS__); \
return; \
} while (0)
namespace Nyaan {
void solve();
}
int main() { Nyaan::solve(); }
//
using namespace std;
template <int DIM, typename Data_t = long long>
struct DimensionExpandedGraph {
static_assert(is_signed<Data_t>::value, "Data_t must be signed.");
using DG = DimensionExpandedGraph;
struct A : array<int, DIM> {
using array<int, DIM>::operator[];
#pragma GCC diagnostic ignored "-Wnarrowing"
template <typename... Args>
A(Args... args) : array<int, DIM>({args...}) {}
#pragma GCC diagnostic warning "-Wnarrowing"
A &operator+=(const A &r) {
for (int i = 0; i < DIM; i++) (*this)[i] += r[i];
return *this;
}
A &operator-=(const A &r) {
for (int i = 0; i < DIM; i++) (*this)[i] -= r[i];
return *this;
}
A operator+(const A &r) { return (*this) += r; }
A operator-(const A &r) { return (*this) -= r; }
int id() const { return DG::id(*this); }
friend int id(const A &a) { return DG::id(a); }
bool ok() const { return DG::ok(*this); }
friend bool ok(const A &a) { return DG::ok(a); }
inline bool is_add() const { return (*this)[0] == ADD; }
friend inline bool is_add(const A &a) { return a[0] == ADD; }
vector<A> near() const {
static vector<A> res;
res.clear();
if (is_add() == true) return res;
for (int i = 0; i < DIM; i++) {
A asc(*this), dec(*this);
asc[i]++;
dec[i]--;
if (asc[i] != g_size[i]) res.push_back(asc);
if (dec[i] != -1) res.push_back(dec);
}
return res;
}
friend vector<A> near(const A &a) { return a.near(); }
};
static int N, add_node;
static A g_size, coeff;
static constexpr int ADD = numeric_limits<int>::min();
static int id(const A &a) {
if (a[0] == ADD) return N + a[1];
int ret = 0;
for (int i = 0; i < DIM; i++) {
ret += a[i] * coeff[i];
}
return ret;
}
template <typename... T>
static int id(const T &... t) {
return id(A{t...});
}
static bool ok(const A &a) {
if (a[0] == ADD) {
return 0 <= a[1] && a[1] < add_node;
}
for (int i = 0; i < DIM; i++)
if (a[i] < 0 or g_size[i] <= a[i]) return false;
return true;
}
template <typename... T>
static bool ok(const T &... t) {
return ok(A{t...});
}
static A ad(int n) { return A{DG::ADD, n}; };
vector<char> grid;
vector<Data_t> dat;
explicit DimensionExpandedGraph() = default;
template <typename... T>
explicit DimensionExpandedGraph(const T &... t) {
set(t...);
}
template <typename... T>
void set(const T &... t) {
N = 1;
g_size = A{t...};
coeff.fill(1);
for (int i = 0; i < DIM; i++) {
assert(g_size[i] != 0);
for (int j = 0; j < i; j++) coeff[j] *= g_size[i];
N *= g_size[i];
}
dat.resize(N + add_node, -1);
}
void add(int n) {
add_node = n;
dat.resize(N + add_node, -1);
}
void scan(istream &is = std::cin) {
grid.reserve(N);
int l = g_size[DIM - 1];
for (int i = 0; i < N; i += l) {
string s;
is >> s;
copy(begin(s), end(s), back_inserter(grid));
}
}
friend istream &operator>>(istream &is, DG &g) {
g.scan(is);
return is;
}
vector<char> &get_grid() { return grid; }
char &operator()(const A &a) { return grid[id(a)]; }
template <typename... T>
char &operator()(const T &... t) {
return grid[id(t...)];
}
A find(const char &c) {
A a{};
fill(begin(a), end(a), 0);
a[DIM - 1] = -1;
while (true) {
a[DIM - 1]++;
for (int i = DIM - 1;; i--) {
if (a[i] != g_size[i]) break;
if (i == 0) return a;
a[i] = 0;
a[i - 1]++;
}
if ((*this)(a) == c) return a;
}
}
template <typename F, typename Dist_t = Data_t>
vector<Dist_t> bfs(F f, A s) {
vector<Dist_t> dist(N + add_node, -1);
if (!ok(s)) return dist;
vector<A> Q;
dist[id(s)] = 0;
Q.push_back(s);
while (!Q.empty()) {
A c = Q.back();
Q.pop_back();
int dc = dist[id(c)];
f(c, [&](A d) {
if (!ok(d)) return;
if (dist[id(d)] == -1) {
dist[id(d)] = dc + 1;
Q.push_back(d);
}
});
}
return dist;
}
template <typename F, typename Dist_t = Data_t>
vector<Dist_t> bfs01(F f, A s) {
vector<Dist_t> dist(N + add_node, -1);
if (!ok(s)) return dist;
deque<A> Q;
dist[id(s)] = 0;
Q.push_back(s);
while (!Q.empty()) {
A c = Q.front();
Q.pop_front();
int dc = dist[id(c)];
f(c, [&](A d, Data_t w) {
if (!ok(d)) return;
if (dist[id(d)] == -1) {
dist[id(d)] = dc + w;
if (w == 0)
Q.push_front(d);
else
Q.push_back(d);
}
});
}
return dist;
}
template <typename F, typename Dist_t = Data_t>
static vector<Dist_t> dijkstra(F f, A s) {
vector<Dist_t> dist(N, -1);
using P = pair<Dist_t, A>;
auto cmp = [](P &a, P &b) { return a.first > b.first; };
priority_queue<P, vector<P>, decltype(cmp)> Q(cmp);
assert(id(s) != -1);
dist[id(s)] = 0;
Q.emplace(0, s);
while (!Q.empty()) {
Dist_t dc;
A c;
tie(dc, c) = Q.top();
Q.pop();
if (dist[id(c)] < dc) continue;
f(c, [&](A d, Dist_t w) {
if (!ok(d)) return;
if (dist[id(d)] == -1 || dist[id(d)] > dc + w) {
dist[id(d)] = dc + w;
Q.emplace(dc + w, d);
}
});
}
return dist;
}
// Union Find
int find(A u) {
return dat[id(u)] < 0 ? id(u) : dat[id(u)] = find(dat[id(u)]);
}
bool same(A u, A v) { return find(u) == find(v); }
bool unite(A u, A v) {
if ((u = find(u)) == (v = find(v))) return false;
int iu = id(u), iv = id(v);
if (dat[iu] > dat[iv]) swap(iu, iv);
dat[iu] += dat[iv];
dat[iv] = iu;
return true;
}
Data_t size(A u) { return -dat[find(u)]; }
};
template <int DIM, typename Data_t>
int DimensionExpandedGraph<DIM, Data_t>::N = 0;
template <int DIM, typename Data_t>
int DimensionExpandedGraph<DIM, Data_t>::add_node = 0;
template <int DIM, typename Data_t>
typename DimensionExpandedGraph<DIM, Data_t>::A
DimensionExpandedGraph<DIM, Data_t>::g_size;
template <int DIM, typename Data_t>
typename DimensionExpandedGraph<DIM, Data_t>::A
DimensionExpandedGraph<DIM, Data_t>::coeff;
//
using namespace Nyaan;
void Nyaan::solve() {
ini(n,m);
DimensionExpandedGraph<3> g(n,n,2);
vvi fee(n,vi(n));
rep(i,m){
ini(h,w,c);
--h,--w;
fee[h][w]=c;
}
auto d=g.dijkstra(
[&](auto a,auto f) {
each(nx,a.near()){
if(nx[2]!=a[2])continue;
f(nx, 1+fee[nx[0]][nx[1]]);
if(a[2]==0){
auto nx2 =nx;
nx2[2]++;
f(nx2, 1);
}
}
}, {0,0,0}
);
out(min(d[g.id(n-1,n-1,0)],d[g.id(n-1,n-1,1)]));
}