Problem:
Soccer
You are a manager of a prestigious soccer team in the JOI league.
The team has $N$ players numbered from 1 to $N$. The players are practicing hard in order to win the tournament game. The field is a rectangle whose height is $H$ meters and width is $W$ meters. The vertical line of the field is in the north-south direction, and the horizontal line of the field is in the east-west direction. A point in the field is denoted by ($i, j$) if it is $i$-meters to the south and $j$ meters to the east from the northwest corner of the field.
After the practice finishes, players must clear the ball. In the beginning of the clearance, the player $i$ ($1 \leq i \leq N$) stands at ($S_i, T_i$). There is only one ball in the field, and the player 1 has it. You stand at ($S_N, T_N$) with the player $N$. The clearance is finished if the ball is passed to ($S_N, T_N$), and you catch it. You cannot move during the clearance process.
You can ask players to act. But, if a player acts, his
fatigue degree
will be increased according to the action. Here is a list of possible actions of the players. If a player has the ball, he can act (i),(ii), or (iii). Otherwise, he can act (ii) or (iv).
(i) Choose one of the 4 directions (east/west/south/north), and choose a positive integer $p$. Kick the ball to that direction. Then, the ball moves exactly p meters. The kicker does not move by this action, and he loses the ball. His fatigue degree is increased by $A \times p + B$.
(ii) Choose one of the 4 directions (east/west/south/north), and move 1 meter to that direction. If he has the ball, he moves with it. His fatigue degree is increased by $C$ regardless of whether he has the ball or not.
(iii) Place the ball where he stands. He loses the ball. His fatigue degree does not change.
(iv) Take the ball. His fatigue degree does not change. A player can take this action only if he stands at the same place as the ball, and nobody has the ball.
Note that it is possible for a player or a ball to leave the field. More than one players can stand at the same place.
Since the players just finished the practice, their fatigue degrees must not be increased too much. You want to calculate the minimum possible value of the sum of fatigue degrees of the players for the clearance process.
Task
Given the size of the field and the positions of the players, write a program which calculates the minimum possible value of the sum of fatigue degrees of the players for the clearance process.
Input
Read the following data from the standard input.
The first line of input contains two space separated integers $H$, $W$. This means the field is a rectangle whose height is $H$ meters and width is $W$ meters.
The second line contains three space separated integers $A$, $B$, $C$ describing the increment of the fatigue degree by actions.
The third line contains an integer N, the number of players.
The $i$-th line ($1 \leq i \leq N$) of the following $N$ lines contains two space separated integers $S_i$, 
...(truncated)

Submitted solutions:

code_snippet: #include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;

#define X_MAX 500
#define Y_MAX 500
#define N_MAX 100000
#define V_MAX ((X_MAX + 1) * (Y_MAX + 1))
#define LLD "%lld"

typedef long long lnt;
typedef bool bnt;
typedef void vnt;

const lnt LNF = 0x3F3F3F3F3F3F3FLL;
const int dx[] = {-1, 0, +1, 0}, dy[] = {0, -1, 0, +1};

int X, Y, N, i, k, x, y, u, v, sx, sy, tx, ty, Ql = -1, Qr = -1, Q[V_MAX * 2];
lnt A, B, C, dir[X_MAX + 1][Y_MAX + 1], dis[X_MAX + 1][Y_MAX + 1][3];

inline bnt chk(int x, int y) { 
    return x >= 0 && x <= X && y >= 0 && y <= Y; 
}

struct dat {
    int k, x, y;
    lnt d;
    bool operator<(const dat &p) const { 
        return d > p.d; 
    }
};

priority_queue<dat> P;

int main() {
    scanf("%d %d" LLD LLD LLD "%d", &X, &Y, &A, &B, &C, &N);

    for (x = 0; x <= X; ++x)
        for (y = 0; y <= Y; ++y)
            dir[x][y] = -1;

    scanf("%d %d", &sx, &sy);
    dir[sx][sy] = 0;

    for (i = 2; i < N; ++i) {
        scanf("%d %d", &x, &y);
        dir[x][y] = 0;
    }

    scanf("%d %d", &tx, &ty);
    dir[tx][ty] = 0;

    for (x = 0; x <= X; ++x)
        for (y = 0; y <= Y; ++y)
            if (!dir[x][y])
                Q[++Qr] = x, Q[++Qr] = y;

    while (Ql < Qr) {
        x = Q[++Ql], y = Q[++Ql];
        for (k = 0; k < 4; ++k) {
            if (chk(u = x + dx[k], v = y + dy[k]) && dir[u][v] == -1) {
                dir[u][v] = dir[x][y] + C;
                Q[++Qr] = u, Q[++Qr] = v;
            }
        }
    }

    for (k = 0; k < 3; ++k)
        for (x = 0; x <= X; ++x)
            for (y = 0; y <= Y; ++y)
                dis[x][y][k] = LNF;

    P.push({2, sx, sy, 0});

    dat p;
    while (true) {
        p = P.top();
        P.pop();

        if (dis[p.x][p.y][p.k] < LNF)
            continue;

        if (p.x == tx && p.y == ty)
            break;

        dis[p.x][p.y][p.k] = p.d;

        switch (p.k) {
            case 2:
                for (k = 0; k < 2; ++k)
                    if (dis[p.x][p.y][k] == LNF)
                        P.push({k, p.x, p.y, p.d + B});
                for (k = 0; k < 4; ++k)
                    if (chk(u = p.x + dx[k], v = p.y + dy[k]) && dis[u][v][2] == LNF)
                        P.push({p.k, u, v, p.d + C});
                break;
            default:
                if (dis[p.x][p.y][2] == LNF)
                    P.push({2, p.x, p.y, p.d + dir[p.x][p.y]});
                for (k = p.k; k < 4; k += 2)
                    if (chk(u = p.x + dx[k], v = p.y + dy[k]) && dis[u][v][p.k] == LNF)
                        P.push({p.k, u, v, p.d + A});
        }
    }

    printf(LLD "\n", p.d);
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 26580
final_rank: 2

code_snippet: #include <bits/stdc++.h>
// #include <atcoder/modint>

#define rep(i, x) for (ll i = 0; i < x; i++)
#define rep2(i, x) for (ll i = 1; i <= x; i++)
#define rep3(i, x, y) for (ll i = x; i < y; i++)
#define REP(i, x) for (ll i = x - 1; i >= 0; i--)
#define REP2(i, x) for (ll i = x; i >= 1; i--)
#define mpa make_pair
#define mpt make_tuple
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define puts(x) cout << (x) << "\n"
using ll = long long;
using ld = long double;
using namespace std;
// using namespace atcoder;

const ll INF = 1000000000000000000;
const int intINF = 1000000000;
const ll mod = 1000000007;
const ll MOD = 998244353;
const ld pi = acos(-1);
// const ld EPS = 1e-9;
typedef string::const_iterator State;
class ParseError
{
};

template <typename T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}
template <typename T>
bool chmin(T &a, const T &b)
{
    if (a > b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}

bool isprime(ll p)
{
    if (p == 1)
        return false;
    for (ll i = 2; i * i <= p; i++)
    {
        if (p % i == 0)
            return false;
    }
    return true;
}
//エラトステネスの篩
vector<bool> isprime_format(ll n)
{
    vector<bool> P(n + 1, 1);
    P[0] = P[1] = 1;
    for (ll i = 2; i * i <= n; i++)
    {
        if (!P[i])
            continue;
        for (int j = i + i; j <= n; j += i)
            P[j] = false;
    }
    return P;
}
vector<ll> prime_format(ll n)
{
    vector<bool> P = isprime_format(n);
    vector<ll> ans;
    for (int i = 2; i <= n; i++)
    {
        if (P[i])
            ans.push_back(i);
    }
    return ans;
}
ll extGCD(ll a, ll b, ll &x, ll &y)
{
    // ax + by = cが整数解をもつための必要十分条件は c が gcd(a,b) で割り切れること。
    //  返り値: a と b の最大公約数
    //  ax + by = gcd(a, b) を満たす (x, y) が格納される
    // main関数内に extGCD(a, b, x, y); でx, yに解が格納
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    ll d = extGCD(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
ll keta(ll n)
{
    ll res = 0;
    while (n >= 1)
    {
        // res++;
        res += n % 10;

        n /= 10;
    }
    return res;
}
ll modpow(ll x, ll y, ll m)
{
    ll res = 1;
    while (y)
    {
        if (y % 2)
        {
            res *= x;
            res %= m;
        }
        x = x * x % m;
        y /= 2;
    }
    return res;
}

unsigned int xorshift()
{
    // xorshift　from 「ビット演算 (bit 演算) の使い方を総特集！ 」
    // 1~6まで出したいときは
    // xorshift() % 6 + 1
    static unsigned int tx = 123456789, ty = 362436069, tz = 521288629, tw = 88675123;
    unsigned int tt = (tx ^ (tx << 11));
    tx = ty;
    ty = tz;
    tz = tw;
    return (tw = (tw ^ (tw >> 19)) ^ (tt ^ (tt >> 8)));
}
uint64_t seed = 123456789;
uint64_t xorshift64()
{
    seed ^= seed << 13;
    seed ^= seed >> 17;
    seed ^= seed << 7;
    return seed;
}
int rand_int(int l, int r)
{
    return l + int(xorshift64() % (r - l));
}
double randouble()
{
    return double(xorshift64()) / double(uint64_t(-1));
}

typedef pair<ll, ll> P;
typedef pair<ll, P> pp;
//左上右下
ll dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
ll ndx[4] = {1, -1, -1, 1}, ndy[4] = {1, 1, -1, -1};
char ds[4] = {'l', 'u', 'r', 'd'};
char dl[4] = {'L', 'U', 'R', 'D'};

vector<ll> spf;
void smallest_prime_factors(ll n)
{
    spf.resize(n + 1);
    spf[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        if (!spf[i])
        {
            for (int j = i; j < n; j += i)
            {
                spf[j] = i;
            }
        }
    }
}
std::map<int, int> high_speed_prime_factor(int n)
{
    std::map<int, int> res;
    while (n != 1)
    {
        res[spf[n]]++;
        n /= spf[n];
    }
    return res;
}

////////////////////////////////struct

struct Comb
{
    // https://atcoder.jp/contests/abc156/submissions/33741990

    ll nCrMAX;
    ll m;
    vector<ll> fac, finv, inv; // n!、1/n!、1/n

    Comb(ll kMOD, ll kMAX = 612345)
    {
        nCrMAX = kMAX;
        m = kMOD;
        fac.resize(nCrMAX);
        finv.resize(nCrMAX);
        inv.resize(nCrMAX);

        fac[0] = fac[1] = 1;
        finv[0] = finv[1] = 1;
        inv[1] = 1;
        for (int i = 2; i < nCrMAX; i++)
        {
            fac[i] = fac[i - 1] * i % m;
            inv[i] = m - inv[m % i] * (m / i) % m;
            finv[i] = finv[i - 1] * inv[i] % m;
        }
    }

    ll nCr(ll n, ll k)
    {
        if (k < nCrMAX)
        {
            ll res = 1;
            for (int i = n - k + 1; i <= n; i++)
            {
                res *= i;
                res %= m;
            }
            res = res * finv[k] % m;
            return res;
        }
        else
        {
            if (n < k)
                return 0;
            if (n < 0 || k < 0)
                return 0;
            return fac[n] * (finv[k] * finv[n - k] % m) % m;
        }
    }

    ll nCr1(ll n, ll k)
    {
        if (n < k)
            return 0;
        if (n < 0 || k < 0)
            return 0;
        return fac[n] * (finv[k] * finv[n - k] % m) % m;
    }

    //(nが大きくて)kが小さい時
    // nCrMAXはk+2まででOK
    ll nCr2(ll n, ll k)
    {
        ll res = 1;
        for (int i = n - k + 1; i <= n; i++)
        {
            res *= i;
            res %= m;
        }
        res = res * finv[k] % m;
        return res;
    }
};

struct status
{
    ll v;
    ll p;

    // bool operator<(const status& rhs) const { return c < rhs.c; };
    // bool operator>(const status& rhs) const { return c > rhs.c; };
    bool operator<(const status &rhs) const { return v < rhs.v; };
    bool operator>(const status &rhs) const { return v > rhs.v; };
};
void yes(bool a) { cout << (a ? "yes" : "no") << endl; }
void YES(bool a) { cout << (a ? "YES" : "NO") << endl; }
void Yes(bool a) { cout << (a ? "Yes" : "No") << endl; }
void Possible(bool a) { cout << (a ? "Possible" : "Impossible") << endl; }
// struct edge {
//	ll to; ll cost;
// };

struct Point
{
    ll x, y;
    Point operator+(const Point &p) const noexcept { return {x + p.x, y + p.y}; }
    Point operator-(const Point &p) const noexcept { return {x - p.x, y - p.y}; }
    Point operator*(const ll k) const noexcept { return {x * k, y * k}; }
    Point operator/(const ll k) const noexcept { return {x / k, y / k}; }
    Point &operator+=(const Point &p) noexcept
    {
        x += p.x;
        y += p.y;
        return *this;
    }
    Point &operator-=(const Point &p) noexcept
    {
        x -= p.x;
        y -= p.y;
        return *this;
    }
    bool operator<(const Point &p) const noexcept { return (x != p.x ? x < p.x : y < p.y); }
};

// using mint = modint998244353;

struct edge
{
    ll to, cost;
};

// O(ElogV)
ll H, W;
ll d[753456];           //始点sから終点tまでのコストd[t]
vector<edge> G[753456]; //コスト
void dijkstra(ll s)
{
    // greater<P>を指定→firstが小さい順
    priority_queue<P, vector<P>, greater<P>> que;
    fill(d, d + 753456, INF); //←TLE気を付ける
    d[s] = 0;
    que.push(P(0, s));
    while (!que.empty())
    {
        P p = que.top();
        que.pop();
        int v = p.second;
        // cout << p.first << ' ' << v / (H * W) << ' ' << (v % (H * W)) / H << ' ' << (v % (H * W)) % H << endl;
        if (d[v] < p.first)
        {
            continue;
        }
        for (int i = 0; i < G[v].size(); i++)
        {
            edge e = G[v][i];
            if (d[e.to] > d[v] + e.cost)
            {
                d[e.to] = d[v] + e.cost;
                que.push(P(d[e.to], e.to));
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    // cout << fixed << setprecision(15);
    // priority_queue<ll, vector<ll>, greater<ll>> que;
    // priority_queue<P, vector<P>, greater<P>> que;
    // priority_queue<status, vector<status>, greater<status>> que;

    cin >> H >> W;
    H++;
    W++;
    ll A, B, C;
    cin >> A >> B >> C;
    ll N;
    cin >> N;
    vector<Point> people(N);
    rep(i, N)
    {
        cin >> people[i].x >> people[i].y;
    }

    ////////////////////////////
    //　costを作る
    //
    vector<vector<ll>> cost(H, vector<ll>(W, -1));
    queue<Point> que;
    rep(i, N)
    {
        que.push(people[i]);
        cost[people[i].x][people[i].y] = 0;
    }
    while (!que.empty())
    {
        Point p = que.front();
        que.pop();
        rep(l, 4)
        {
            ll nx = p.x + dx[l], ny = p.y + dy[l];
            if (0 <= nx && nx < H && 0 <= ny && ny < W && cost[nx][ny] == -1)
            {
                cost[nx][ny] = cost[p.x][p.y] + C;
                que.push({nx, ny});
            }
        }
    }

    ////////////////////////////
    //　グラフの構築
    //
    //  1層目
    rep(i, H)
    {
        rep(j, W)
        {
            rep(l, 4)
            {
                ll nx = i + dx[l], ny = j + dy[l];
                if (0 <= nx && nx < H && 0 <= ny && ny < W)
                {
                    G[i * W + j].push_back({nx * W + ny, C});
                }
            }
        }
    }
    //  2層目（横）
    rep(i, H)
    {
        rep(j, W)
        {
            // 1層目と2層目の間
            G[i * W + j].push_back({H * W + i * W + j, B});
            G[H * W + i * W + j].push_back({i * W + j, cost[i][j]});
            // 2層目
            rep(l, 4)
            {
                ll nx = i + dx[l], ny = j + dy[l];
                if (0 <= nx && nx < H && 0 <= ny && ny < W)
                {
                    G[H * W + i * W + j].push_back({H * W + nx * W + ny, A});
                }
                l++; //横なので
            }
        }
    }
    //　3層目（縦）
    rep(i, H)
    {
        rep(j, W)
        {
            // 1層目と3層目の間
            G[i * W + j].push_back({2 * H * W + i * W + j, B});
            G[2 * H * W + i * W + j].push_back({i * W + j, cost[i][j]});
            // 3層目
            rep(l, 4)
            {
                l++; //縦なので
                ll nx = i + dx[l], ny = j + dy[l];
                if (0 <= nx && nx < H && 0 <= ny && ny < W)
                {
                    G[2 * H * W + i * W + j].push_back({2 * H * W + nx * W + ny, A});
                    // cout << i << ' ' << j << ' ' << nx << ' ' << ny << endl;
                }
            }
        }
    }

    dijkstra(people[0].x * W + people[0].y);

    /*rep(i, H)
    {
        rep(j, W)
        {
            cout << cost[i][j] << ' ';
        }
        cout << endl;
    }
    cout << endl;
    rep(i, H)
    {
        rep(j, W)
        {
            cout << d[i * W + j] << ' ';
        }
        cout << endl;
    }
    cout << endl;
    rep(i, H)
    {
        rep(j, W)
        {
            cout << d[H * W + i * W + j] << ' ';
        }
        cout << endl;
    }
    cout << endl;
    rep(i, H)
    {
        rep(j, W)
        {
            cout << d[2 * H * W + i * W + j] << ' ';
        }
        cout << endl;
    }*/

    cout << d[people[N - 1].x * W + people[N - 1].y] << endl;

    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 110044
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; }
template <typename T, typename Can> T bsearch(T L, T R, const Can& can, bool left_feasible = true) {
    static_assert(is_convertible<decltype(can), function<bool(T)>>::value);
    T& feasible = left_feasible ? L : R;
    T& infeasible = left_feasible ? R : L;
    while(R - L > 1) {
        T M = L + (R - L) / 2;
        (can(M) ? feasible : infeasible) = M;
    }
    return feasible;
}
int rot_x(int x, int y) {
    return x + y;
}
int rot_y(int x, int y, int max_y) {
    return x - y + max_y;
}
int max_rot(int max_x, int max_y) {
    return max_x + max_y;
}
int h, w;
ll a, b, c;
int n;
struct node {
    int x, y, kick_dir;
    bool operator<(const node& other) const {
        return id() < other.id();
    }
    int id() const {
        return (x * (w + 1) + y) * 8 + kick_dir;;
    }
};
int dx[] = {0, -1, 1, 0, 0};
int dy[] = {0, 0, 0, -1, 1};
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> h >> w;
    cin >> a >> b >> c;
    cin >> n;
    vector<int> s(n), t(n);
    vector<vector<int>> psum(max_rot(h, w) + 1, vector<int>(max_rot(h, w) + 1));
    for(int i = 0; i < n; i++) {
        cin >> s[i] >> t[i];
        psum[rot_x(s[i], t[i])][rot_y(s[i], t[i], w)]++;
    }
    for(int i = 0; i <= max_rot(h, w); i++) {
        for(int j = 0; j <= max_rot(h, w); j++) {
            psum[i][j] += i > 0 ? psum[i - 1][j] : 0;
            psum[i][j] += j > 0 ? psum[i][j - 1] : 0;
            psum[i][j] -= i > 0 and j > 0 ? psum[i - 1][j - 1] : 0;
        }
    }
    auto rsq = [&](int rx1, int ry1, int rx2, int ry2) {
        return psum[rx2][ry2]
            - (rx1 > 0 ? psum[rx1 - 1][ry2] : 0)
            - (ry1 > 0 ? psum[rx2][ry1 - 1] : 0)
            + (rx1 > 0 and ry1 > 0 ? psum[rx1 - 1][ry1 - 1] : 0);
    };
    auto query = [&](int x, int y, int k) {
        int rx = rot_x(x, y), ry = rot_y(x, y, w);
        return rsq(max(0, rx - k), max(0, ry - k), min(rx + k, max_rot(h, w)), min(ry + k, max_rot(h, w)));
    };
    int max_node_id = node{h, w, 4}.id();
    vector<ll> d(max_node_id + 1, lim<ll>::max()), done(max_node_id + 1);
    priority_queue<pair<ll, node>, vector<pair<ll, node>>, greater<pair<ll, node>>> pq;
    auto expand = [&](const node& u, const node& v, ll weight) {
        if(0 <= v.x and v.x <= h and 0 <= v.y and v.y <= w and d[v.id()] > d[u.id()] + weight) {
            pq.push({d[v.id()] = d[u.id()] + weight, v});
        }
    };
    node start = {s[0], t[0], 0};
    pq.push({d[start.id()] = 0, start});
    while(not pq.empty()) {
        auto [_, u] = pq.top();
        pq.pop();
        if(not done[u.id()]) {
            if(u.kick_dir == 0) {
                int nearest = bsearch(-1, h + w, [&](int k) { return query(u.x, u.y, k) > 0; }, false);
                for(int dir = 1; dir <= 4; dir++) {
                    expand(u, {u.x, u.y, dir}, b + c * nearest);
                    expand(u, {u.x + dx[dir], u.y + dy[dir], 0}, c);
                }
            } else {
                expand(u, {u.x, u.y, 0}, 0);
                expand(u, {u.x + dx[u.kick_dir], u.y + dy[u.kick_dir], u.kick_dir}, a);
            }
            done[u.id()] = true;
        }
    }
    ll ans = lim<ll>::max();
    for(int dir = 0; dir <= 4; dir++) {
        ans = min(ans, d[node{s.back(), t.back(), dir}.id()]);
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 500
memory_kb: 64944
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; }
int h, w;
ll a, b, c;
int n;
struct node {
    int x, y, kick_dir;
    bool operator<(const node& n) const {
        return id() < n.id();
    }
    int id() const {
        return (x * (w + 1) + y) * 8 + kick_dir;;
    }
};
int dx[] = {0, -1, 1, 0, 0};
int dy[] = {0, 0, 0, -1, 1};
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> h >> w;
    cin >> a >> b >> c;
    cin >> n;
    vector<int> s(n), t(n);
    for(int i = 0; i < n; i++) {
        cin >> s[i] >> t[i];
    }
    int max_node_id = node{h, w, 4}.id();
    vector<ll> d(max_node_id + 1, lim<ll>::max()), done(max_node_id + 1);
    priority_queue<pair<ll, node>, vector<pair<ll, node>>, greater<pair<ll, node>>> pq;
    auto expand = [&](const node& u, const node& v, int w) {
        if(d[v.id()] > d[u.id()] + w) {
            pq.push({d[v.id()] = d[u.id()] + w, v});
        }
    };
    node start = {s[0], t[0], 0};
    pq.push({d[start.id()] = 0, start});
    while(not pq.empty()) {
        auto [_, u] = pq.top();
        pq.pop();
        if(not done[u.id()]) {
            if(u.kick_dir == 0) {
                for(int dir = 1; dir <= 4; dir++) {
                    int nearest = lim<int>::max();
                    for(int i = 0; i < n; i++) {
                        nearest = min(nearest, abs(s[i] - u.x) + abs(t[i] - u.y));
                    }
                    expand(u, {u.x, u.y, dir}, b + c * nearest);
                    int nx = u.x + dx[dir], ny = u.y + dy[dir];
                    if(0 <= nx and nx <= h and 0 <= ny and ny <= w) {
                        expand(u, {nx, ny, u.kick_dir}, c);
                    }
                }
            } else {
                expand(u, {u.x, u.y, 0}, 0);
                int nx = u.x + dx[u.kick_dir], ny = u.y + dy[u.kick_dir];
                if(0 <= nx and nx <= h and 0 <= ny and ny <= w) {
                    expand(u, {nx, ny, u.kick_dir}, a);
                }
            }
            done[u.id()] = true;
        }
    }
    ll ans = lim<ll>::max();
    for(int dir = 0; dir <= 4; dir++) {
        ans = min(ans, d[node{s.back(), t.back(), dir}.id()]);
    }
    cout << ans << endl;
    return 0;
}
accuracy: 0.15384615384615385
time_ms: 250
memory_kb: 48404
final_rank: 20

code_snippet: // #pragma GCC target("avx")  // CPU 処理並列化
// #pragma GCC optimize("O3")  // CPU 処理並列化
// #pragma GCC optimize("unroll-loops")  // 条件処理の呼び出しを減らす
// #define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
// #define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<deque>
#include<stack>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<stdlib.h>
#include<cassert>
#include<time.h>
#include<bitset>
#include<numeric>
#include<unordered_set>
#include<unordered_map>
#include<complex>
using namespace std;
const long long mod=1000000007;
const long long inf=mod*mod;
const long long d2=(mod+1)/2;
const long double EPS=1e-20;
const double INF=1e+10;
const double PI=acos(-1.0);
const int C_SIZE = 3100000;
const int UF_SIZE = 4100000;
namespace{
	long long fact[C_SIZE];
	long long finv[C_SIZE];
	long long inv[C_SIZE];
	long long Comb(int a,int b){
	 	if(a<b||b<0)return 0;
	 	return fact[a]*finv[b]%mod*finv[a-b]%mod;
	}
	void init_C(int n){
		fact[0]=finv[0]=inv[1]=1;
		for(int i=2;i<n;i++){
			inv[i]=(mod-(mod/i)*inv[mod%i]%mod)%mod;
		}
		for(int i=1;i<n;i++){
			fact[i]=fact[i-1]*i%mod;
			finv[i]=finv[i-1]*inv[i]%mod;
		}
	}
	long long pw(long long a,long long b){
		if(a<0LL)return 0;
		if(b<0LL)return 0;
		long long ret=1;
		while(b){
			if(b%2)ret=ret*a%mod;
			a=a*a%mod;
			b/=2;
		}
		return ret;
	}
	long long pw_mod(long long a,long long b,long long M){
		if(a<0LL)return 0;
		if(b<0LL)return 0;
		long long ret=1;
		while(b){
			if(b%2)ret=ret*a%M;
			a=a*a%M;
			b/=2;
		}
		return ret;
	}
	int pw_mod_int(int a,int b,int M){
		if(a<0)return 0;
		if(b<0)return 0;
		int ret=1;
		while(b){
			if(b%2)ret=(long long)ret*a%M;
			a=(long long)a*a%M;
			b/=2;
		}
		return ret;
	}
	int ABS(int a){return max(a,-a);}
	long long ABS(long long a){return max(a,-a);}
	double ABS(double a){return max(a,-a);}
	int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
	int UF[UF_SIZE];
	void init_UF(int n){
		for(int i=0;i<n;i++)UF[i]=-1;
	}
	int FIND(int a){
		if(UF[a]<0)return a;
		return UF[a]=FIND(UF[a]);
	}
	void UNION(int a,int b){
		a=FIND(a);b=FIND(b);if(a==b)return;
		if(UF[a]>UF[b])swap(a,b);
		UF[a]+=UF[b];UF[b]=a;
	}
}
// ここから編集しろ
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
int v[510][510][6];
long long ijk[510][510][6];
int x[110000];
int y[110000];
int bfs[510][510];
int main(){
	int h,w,a,b,c,n;
	scanf("%d%d%d%d%d%d",&h,&w,&a,&b,&c,&n);
	for(int i=0;i<=h;i++)for(int j=0;j<=w;j++){
		bfs[i][j]=-1;
	}
	queue<pair<int,int> > q;
	for(int i=0;i<n;i++){
		scanf("%d%d",x+i,y+i);
		bfs[x[i]][y[i]]=0;
		q.push(make_pair(x[i],y[i]));
	}
	while(q.size()){
		int row=q.front().first;
		int col=q.front().second;
		q.pop();
		for(int i=0;i<4;i++){
			int tr=row+dx[i];
			int tc=col+dy[i];
			if(tr<0||tc<0||tr>h||tc>w)continue;
			if(bfs[tr][tc]!=-1)continue;
			bfs[tr][tc]=bfs[row][col]+1;
			q.push(make_pair(tr,tc));
		}
	}
	for(int i=0;i<=h;i++)for(int j=0;j<=w;j++)for(int k=0;k<6;k++)ijk[i][j][k]=inf;
	ijk[x[0]][y[0]][0]=0;
	priority_queue<pair<long long,pair<pair<int,int>,int> > > Q;
	Q.push(make_pair(0LL,make_pair(make_pair(x[0],y[0]),0)));
	while(Q.size()){
		long long cost=-Q.top().first;
		int row=Q.top().second.first.first;
		int col=Q.top().second.first.second;
		int ty=Q.top().second.second;
		Q.pop();
		if(v[row][col][ty])continue;
		v[row][col][ty]=1;
		if(ty==0){
			if(!v[row][col][1]&&ijk[row][col][1]>cost+(long long)bfs[row][col]*c){
				ijk[row][col][1]=cost+(long long)bfs[row][col]*c;
				Q.push(make_pair(-ijk[row][col][1],make_pair(make_pair(row,col),1)));
			}
		}else if(ty==1){
			for(int i=0;i<4;i++){
				int tr=row+dx[i];
				int tc=col+dy[i];
				if(tr<0||tc<0||tr>h||tc>w)continue;
				if(v[tr][tc][ty])continue;
				if(ijk[tr][tc][ty]>cost+c){
					ijk[tr][tc][ty]=cost+c;
					Q.push(make_pair(-cost-c,make_pair(make_pair(tr,tc),ty)));
				}
			}
			if(!v[row][col][0]&&ijk[row][col][0]>cost){
				ijk[row][col][0]=cost;
				Q.push(make_pair(-ijk[row][col][0],make_pair(make_pair(row,col),0)));
			}
			for(int i=0;i<4;i++){
				int tt=2+i;
				long long toc=cost+b;
				if(v[row][col][tt])continue;
				if(ijk[row][col][tt]>toc){
					ijk[row][col][tt]=toc;
					Q.push(make_pair(-toc,make_pair(make_pair(row,col),tt)));
				}
			}
		}else{
			if(!v[row][col][0]&&ijk[row][col][0]>cost){
				ijk[row][col][0]=cost;
				Q.push(make_pair(-ijk[row][col][0],make_pair(make_pair(row,col),0)));
			}
			int tr=row+dx[ty-2];
			int tc=col+dy[ty-2];
			long long toc=cost+a;
			if(0<=tr&&tr<=h&&0<=tc&&tc<=w&&!v[tr][tc][ty]&&ijk[tr][tc][ty]>toc){
				ijk[tr][tc][ty]=toc;
				Q.push(make_pair(-toc,make_pair(make_pair(tr,tc),ty)));
			}
		}
	}
	printf("%lld\n",ijk[x[n-1]][y[n-1]][0]);
}
accuracy: 1
time_ms: 360
memory_kb: 28956
final_rank: 8

code_snippet: #include <bits/stdc++.h>
 
//    #include <boost/multiprecision/cpp_int.hpp>
 #define int long long
 #define inf  1000000007
 #define pa pair<int,int>
 #define ll long long
 #define pal pair<double,double>
 #define ppap pair<pa,int>
  #define PI 3.14159265358979323846
  #define paa pair<int,char>
  #define  mp make_pair
  #define  pb push_back
  #define EPS (1e-8)
                                          
    int dx[8]={0,1,0,-1,1,1,-1,-1};
    int dy[8]={1,0,-1,0,-1,1,1,-1};
                                            using namespace std;
                                   			class pa3{
                                            	public:
                                            	int x;
                                   				int y,z;
                                            	pa3(int x=0,int y=0,int z=0):x(x),y(y),z(z) {}
                                            	bool operator < (const pa3 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		 return z<p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                   				bool operator > (const pa3 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		 return z>p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa3 &p) const{
                                            		return x==p.x && y==p.y && z==p.z;
                                            	}
                                            		bool operator != (const pa3 &p) const{
                                            			return !( x==p.x && y==p.y && z==p.z);
                                            	}
                                            
                                            };
                                            
                                            class pa4{
                                            	public:
                                            	int x;
                                            	int y,z,w;
                                            	pa4(int x=0,int y=0,int z=0,int w=0):x(x),y(y),z(z),w(w) {}
                                            	bool operator < (const pa4 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		if(z!=p.z)return z<p.z;
                                            		return w<p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator > (const pa4 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		if(z!=p.z)return z>p.z;
                                            		return w>p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa4 &p) const{
                                            		return x==p.x && y==p.y && z==p.z &&w==p.w;
                                            	}
                                            		
                                            
                                            };
                                            class pa2{
                                            	public:
                                            	int x,y;
                                            	pa2(int x=0,int y=0):x(x),y(y) {}
                                            	pa2 operator + (pa2 p) {return pa2(x+p.x,y+p.y);}
                                            	pa2 operator - (pa2 p) {return pa2(x-p.x,y-p.y);}
                                            	bool operator < (const pa2 &p) const{
                                            		return y != p.y ? y<p.y: x<p.x;
                                            	}
                                            	bool operator > (const pa2 &p) const{
                                            		return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa2 &p) const{
                                            		return abs(x-p.x)==0 && abs(y-p.y)==0;
                                            	}
                                            	bool operator != (const pa2 &p) const{
                                            		return !(abs(x-p.x)==0 && abs(y-p.y)==0);
                                            	}
                                            		
                                            
                                            };
                                            
 
                      
                                string itos( int i ) {
                                ostringstream s ;
                                s << i ;
                                return s.str() ;
                                }
                                 
                                int gcd(int v,int b){
                                	if(v==0) return b;
                                	if(b==0) return v;
                                	if(v>b) return gcd(b,v);
                                	if(v==b) return b;
                                	if(b%v==0) return v;
                                	return gcd(v,b%v);
                                }
                 
                            
                                int mod;
int extgcd(int a, int b, int &x, int &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    int d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
pa operator+(const pa & l,const pa & r) {   
    return {l.first+r.first,l.second+r.second};                                    
}    
pa operator-(const pa & l,const pa & r) {   
    return {l.first-r.first,l.second-r.second};                                    
}  
                                
                int pr[10000100];
                int inv[10000010];
                
                int beki(int wa,int rr,int warukazu){
                	if(rr==0) return 1%warukazu;
                	if(rr==1) return wa%warukazu;
                	wa%=warukazu;
                	if(rr%2==1) return ((ll)beki(wa,rr-1,warukazu)*(ll)wa)%warukazu;
                	ll zx=beki(wa,rr/2,warukazu);
                	return (zx*zx)%warukazu;
                }
 
                
    			int comb(int nn,int rr){
    				if(rr<0 || rr>nn || nn<0) return 0;
    				int r=pr[nn]*inv[rr];
    				r%=mod;
    				r*=inv[nn-rr];
    				r%=mod;
    				return r;
    			}
               
                void gya(int ert){
                	pr[0]=1;
                	for(int i=1;i<=ert;i++){
                		pr[i]=(pr[i-1]*i)%mod;
                	}
                		inv[ert]=beki(pr[ert],mod-2,mod);
                	for(int i=ert-1;i>=0;i--){
                		inv[i]=inv[i+1]*(i+1)%mod;
                	}
                }
                
              //   cin.tie(0);
    		//	ios::sync_with_stdio(false);
    			//priority_queue<pa3,vector<pa3>,greater<pa3>> pq;            
                 //sort(ve.begin(),ve.end(),greater<int>());
 //   mt19937(clock_per_sec);
  //  mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()) ;


int dis[510][510]={};
int memo[510][510][3]={};
//bool vis[510][510][2]={};

signed main(){
	
	
   cin.tie(0);
	ios::sync_with_stdio(false);

int h,w;
	cin>>h>>w;
	const int inff=inf*100000000ll;
	for(int i=0;i<=500;i++)for(int j=0;j<=500;j++)dis[i][j]=inf,memo[i][j][0]=inff,memo[i][j][1]=inff,memo[i][j][2]=inff;
	int a,b,c;
	cin>>a>>b>>c;
	queue<pa3> qu;
	int n;
	cin>>n;
	int gx,gy;
	priority_queue<pa4,vector<pa4>,greater<pa4>> pq;  
	for(int i=0;i<n;i++){
		int x,y;
		cin>>x>>y;
			qu.push((pa3){x,y,b});
		if(i==0){
				pq.push((pa4){0,x,y,0});
			memo[x][y][0]=0;
		
		}
		if(i==n-1){
			gx=x,gy=y;
		}
	}
	while(qu.size()){
		pa3 z=qu.front();
		qu.pop();
		if(dis[z.x][z.y]!=inf) continue;
		dis[z.x][z.y]=z.z;
	//	cout<<z.x<<" "<<z.y<<"  "<<z.z<<endl;
		for(int r=0;r<4;r++){
			int X=z.x+dx[r];
			int Y=z.y+dy[r];
			
				if(X>=0 && Y>=0 && X<=h && Y<=w)qu.push((pa3){X,Y,z.z+c});
		}
	}
	
	int cnt=0;
	//for(int i=0;i<10;i++)for(int j=0;j<10;j++)cout<<dis[i][j]<<endl;
	while(pq.size()){
		pa4 z=pq.top();
		pq.pop();
		
		if(memo[z.y][z.z][z.w]<z.x)continue;
	//	cout<<z.y<<" "<<z.z<<" "<<z.w<<"   "<<z.x<<endl;
		//cnt++;
		if(z.y==gx&& z.z==gy && z.w==0){
			cout<<z.x<<endl;
			return 0;
		}
		if(z.w==0){
			for(int r=0;r<4;r++){
				int X=z.y+dx[r],Y=z.z+dy[r];
				if(X>=0 && X<=h && Y>=0 && Y<=w){
					if(memo[X][Y][0]>z.x+c){
							pq.push(pa4({z.x+c,X,Y,0}));
						memo[X][Y][0]=z.x+c;
					}
				}
			}
			for(int r=1;r<3;r++)if(memo[z.y][z.z][r]>z.x){
					pq.push((pa4){z.x,z.y,z.z,r});
				memo[z.y][z.z][r]=z.x;
			}
		}
		
		if(z.w==1){
			for(int r=0;r<4;r++)if(dy[r]==0){
				int X=z.y+dx[r],Y=z.z+dy[r];
				if(X>=0 && X<=h && Y>=0 && Y<=w){
					if(memo[X][Y][1]>z.x+a){
							pq.push(pa4({z.x+a,X,Y,1}));
						memo[X][Y][1]=z.x+a;
					}
				}
			}
			
			for(int r=0;r<1;r++)if(memo[z.y][z.z][r]>z.x+dis[z.y][z.z]){
					pq.push((pa4){z.x+dis[z.y][z.z],z.y,z.z,r});
				memo[z.y][z.z][r]=z.x+dis[z.y][z.z];
			}
		}
		
		
		if(z.w==2){
			for(int r=0;r<4;r++)if(dx[r]==0){
				int X=z.y+dx[r],Y=z.z+dy[r];
				if(X>=0 && X<=h && Y>=0 && Y<=w){
					if(memo[X][Y][2]>z.x+a){
							pq.push(pa4({z.x+a,X,Y,2}));
						memo[X][Y][2]=z.x+a;
					}
				}
			}
			//int r=0;
			for(int r=0;r<1;r++)if(memo[z.y][z.z][r]>z.x+dis[z.y][z.z]){
					pq.push((pa4){z.x+dis[z.y][z.z],z.y,z.z,r});
				memo[z.y][z.z][r]=z.x+dis[z.y][z.z];
			}
		}
		
		
		
	}
	cout<<min(memo[gx][gy][0],memo[gx][gy][1])<<endl;
	
	return 0;
	

 
 }
accuracy: 1
time_ms: 150
memory_kb: 24092
final_rank: 1

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<functional>
using namespace std;
#define ll long long
const ll linf = 1e15;
struct node{
    int h, w;
    ll cost;
    bool operator<(const node &n1) const {
        return n1.cost < cost;
    }
};

struct edge{
    int h, w, k;
    ll cost;
    bool operator<(const edge &e1) const {
        return e1.cost < cost;
    }
};

int H, W, N;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
ll A, B, C;
ll D[501][501][5], near[501][501];
int ph[100010], pw[100010];

void dijk(){
    for(int i = 0; i <= H; i++){
        for(int j = 0; j <= W; j++){
            near[i][j] = linf;
        }
    }
    priority_queue<node> pq;
    for(int i = 1; i <= N; i++){
        near[ph[i]][pw[i]] = 0;
        pq.push(node{ph[i], pw[i], 0});
    }
    
    while(!pq.empty()){
        int h = pq.top().h;
        int w = pq.top().w;
        ll cost = pq.top().cost;
        pq.pop();
        if(near[h][w] < cost) continue;
        
        cost++;
        for(int i = 0; i < 4; i++){
            int nh = h + dx[i];
            int nw = w + dy[i];
            if(nh < 0 || H < nh) continue;
            if(nw < 0 || W < nw) continue;
            if(near[nh][nw] > cost){
                near[nh][nw] = cost;
                pq.push(node{nh, nw, cost});
            }
        }
    }
}

ll solve(){
    dijk();
    for(int i = 0; i <= H; i++){
        for(int j = 0; j <= W; j++){
            for(int k = 0; k <= 4; k++){
                D[i][j][k] = linf;
            }
        }
    }
    priority_queue<edge> pq;
    pq.push(edge{ph[1], pw[1], 4, 0});
    D[ph[1]][pw[1]][4] = 0;

    while(!pq.empty()){
        int h = pq.top().h;
        int w = pq.top().w;
        int k = pq.top().k;
        ll cost = pq.top().cost;
        pq.pop();

        if(D[h][w][k] < cost) continue;

        if(k == 4){
            for(int i = 0; i < 4; i++){
                int nh = h + dx[i];
                int nw = w + dy[i];
                if(nh < 0 || H < nh) continue;
                if(nw < 0 || W < nw) continue;
                if(D[nh][nw][k] > cost + C){
                    D[nh][nw][k] = cost + C;
                    pq.push(edge{nh, nw, k, cost + C});
                }
            }
            for(int i = 0; i < 4; i++){
                ll new_c = cost + B;
                if(D[h][w][i] > new_c){
                    D[h][w][i] = new_c;
                    pq.push(edge{h, w, i, new_c});
                }
            }
        }else{
            ll new_c = cost + near[h][w] * C;
            if(D[h][w][4] > new_c){
                D[h][w][4] = new_c;
                pq.push(edge{h, w, 4, new_c});
            }
            
            new_c = cost + A;
            int nh = h + dx[k];
            int nw = w + dy[k];
            if(nh < 0 || H < nh) continue;
            if(nw < 0 || W < nw) continue;
            if(D[nh][nw][k] > new_c){
                D[nh][nw][k] = new_c;
                pq.push(edge{nh, nw, k, new_c});
            }
        }
    }
    ll ans = linf;
    for(int i = 0; i <= 4; i++){
        ans = min(ans, D[ph[N]][pw[N]][i]);
    }
    return ans;
}

void init(){
    cin >> H >> W >> A >> B >> C >> N;
    for(int i = 1; i <= N; i++){
        cin >> ph[i] >> pw[i];
    }
}

int main(){
    init();
    cout << solve() << endl;
    return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 24584
final_rank: 6

code_snippet: #include <iostream>
#include <queue>
#include <functional>
#include <tuple>
using namespace std;

long long dist[509][509][5], dp[509][509], H, W, A, B, C, N, sx, sy, gx, gy;
priority_queue<tuple<long long, int, int, int>, vector<tuple<long long, int, int, int>>, greater<tuple<long long, int, int, int>>>que;
priority_queue<tuple<long long, int, int>, vector<tuple<long long, int, int>>, greater<tuple<long long, int, int>>>que2;

int main() {
	cin >> H >> W >> A >> B >> C >> N;
	for (int i = 0; i <= H; i++) { for (int j = 0; j <= W; j++) dp[i][j] = (1LL << 30); }
	for (int i = 1; i <= N; i++) {
		long long x, y; cin >> x >> y;
		if (i == 1) { sx = x; sy = y; }
		if (i == N) { gx = x; gy = y; }
		dp[x][y] = 0; que2.push(make_tuple(0, x, y));
	}

	// パート A
	while (!que2.empty()) {
		int p1 = get<1>(que2.top()), p2 = get<2>(que2.top()); que2.pop();
		int dx[4] = { 0, 1, 0, -1 }, dy[4] = { 1, 0, -1, 0 };

		for (int i = 0; i < 4; i++) {
			int fx = p1 + dx[i], fy = p2 + dy[i];
			if (fx<0 || fy<0 || fx>H || fy>W) continue;
			if (dp[fx][fy] > dp[p1][p2] + C) {
				dp[fx][fy] = dp[p1][p2] + C;
				que2.push(make_tuple(dp[fx][fy], fx, fy));
			}
		}
	}

	// パート B

	for (int i = 0; i <= H; i++) { for (int j = 0; j <= W; j++) { for (int k = 0; k < 5; k++) dist[i][j][k] = (1LL << 60); } }
	dist[sx][sy][4] = 0; que.push(make_tuple(0, sx, sy, 4));

	while (!que.empty()) {
		int p1 = get<1>(que.top()), p2 = get<2>(que.top()), p3 = get<3>(que.top()); que.pop();

		int dx[4] = { 0, 1, 0, -1 }, dy[4] = { 1, 0, -1, 0 };
		if (p3 == 4) {
			for (int i = 0; i <= 3; i++) {
				int fx = p1 + dx[i], fy = p2 + dy[i];
				if (fx < 0 || fy < 0 || fx > H || fy > W) continue;
				if (dist[fx][fy][4] > dist[p1][p2][p3] + C) {
					dist[fx][fy][4] = dist[p1][p2][p3] + C;
					que.push(make_tuple(dist[fx][fy][4], fx, fy, 4));
				}
			}
			for (int i = 0; i <= 3; i++) {
				if (dist[p1][p2][i] > dist[p1][p2][p3] + B) {
					dist[p1][p2][i] = dist[p1][p2][p3] + B;
					que.push(make_tuple(dist[p1][p2][i], p1, p2, i));
				}
			}
		}
		else {
			int fx = p1 + dx[p3], fy = p2 + dy[p3];
			if (fx >= 0 && fy >= 0 && fx <= H && fy <= W) {
				if (dist[fx][fy][p3] > dist[p1][p2][p3] + A) {
					dist[fx][fy][p3] = dist[p1][p2][p3] + A;
					que.push(make_tuple(dist[fx][fy][p3], fx, fy, p3));
				}
			}
			if (dist[p1][p2][4] > dist[p1][p2][p3] + dp[p1][p2]) {
				dist[p1][p2][4] = dist[p1][p2][p3] + dp[p1][p2];
				que.push(make_tuple(dist[p1][p2][4], p1, p2, 4));
			}
		}
	}
	cout << dist[gx][gy][4] << endl;
	return 0;
}
accuracy: 0.15384615384615385
time_ms: 160
memory_kb: 21088
final_rank: 19

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 505

enum Type{
	STOP,
	FLY_North,
	FLY_East,
	FLY_South,
	FLY_West,
};

struct LOC{
	int row,col;
};

struct Info{
	Info(int arg_row,int arg_col,ll arg_sum_cost){
		loc.row = arg_row;
		loc.col = arg_col;
		sum_cost = arg_sum_cost;
	}
	LOC loc;
	ll sum_cost;
};

struct Edge{
	Edge(int arg_row,int arg_col,Type arg_type,ll arg_cost){
		loc.row = arg_row;
		loc.col = arg_col;
		type = arg_type;
		cost = arg_cost;
	}
	LOC loc;
	Type type;
	ll cost;
};

struct State{
	State(int arg_row,int arg_col,Type arg_type,ll arg_sum_cost){
		loc.row = arg_row;
		loc.col = arg_col;
		type = arg_type;
		sum_cost = arg_sum_cost;
	}
	bool operator<(const struct State &arg) const{
		return sum_cost > arg.sum_cost;
	}
	LOC loc;
	Type type;
	ll sum_cost;
};

int H,W;
int N;
int diff_row[4] = {-1,0,1,0},diff_col[4] = {0,1,0,-1};
ll A,B,C;
ll nearest_cost[NUM][NUM];
ll min_cost[NUM][NUM][5];
bool table[NUM][NUM];
LOC start,goal;
Type type_array[5] = {STOP,FLY_North,FLY_East,FLY_South,FLY_West};
vector<Edge> edge[NUM][NUM][5];

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1){
		return true;
	}else{
		return false;
	}
}

int main(){

	scanf("%d %d",&H,&W);
	H += 1;
	W += 1;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			table[row][col] = false;
		}
	}

	scanf("%lld %lld %lld",&A,&B,&C);

	scanf("%d",&N);

	int tmp_row,tmp_col;

	scanf("%d %d",&start.row,&start.col);
	table[start.row][start.col] = true;

	for(int loop = 1; loop < N-1; loop++){
		scanf("%d %d",&tmp_row,&tmp_col);
		table[tmp_row][tmp_col] = true;
	}

	scanf("%d %d",&goal.row,&goal.col);
	table[goal.row][goal.col] = true;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			nearest_cost[row][col] = HUGE_NUM;
		}
	}

	queue<Info> CALC;
	int adj_row,adj_col;
	ll next_cost;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(!table[row][col])continue;

			nearest_cost[row][col] = 0;
			CALC.push(Info(row,col,0));

			while(!CALC.empty()){

				for(int i = 0; i < 4; i++){

					adj_row = CALC.front().loc.row+diff_row[i];
					adj_col = CALC.front().loc.col+diff_col[i];

					if(!rangeCheck(adj_row,adj_col))continue;

					next_cost = CALC.front().sum_cost+C;

					if(nearest_cost[adj_row][adj_col] > next_cost){

						nearest_cost[adj_row][adj_col] = next_cost;
						CALC.push(Info(adj_row,adj_col,next_cost));
					}
				}
				CALC.pop();
			}
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){

			for(int i = 0; i < 4; i++){

				adj_row = row+diff_row[i];
				adj_col = col+diff_col[i];

				if(!rangeCheck(adj_row,adj_col))continue;

				edge[row][col][STOP].push_back(Edge(adj_row,adj_col,type_array[STOP],C));

				edge[row][col][STOP].push_back(Edge(row,col,type_array[i+1],B));
			}

			edge[row][col][FLY_North].push_back(Edge(row,col,type_array[STOP],nearest_cost[row][col]));
			if(row > 0){
				edge[row][col][FLY_North].push_back(Edge(row-1,col,type_array[FLY_North],A));
			}

			edge[row][col][FLY_East].push_back(Edge(row,col,type_array[STOP],nearest_cost[row][col]));
			if(col+1 < W){
				edge[row][col][FLY_East].push_back(Edge(row,col+1,type_array[FLY_East],A));
			}

			edge[row][col][FLY_South].push_back(Edge(row,col,type_array[STOP],nearest_cost[row][col]));
			if(row+1 < H){
				edge[row][col][FLY_South].push_back(Edge(row+1,col,type_array[FLY_South],A));
			}

			edge[row][col][FLY_West].push_back(Edge(row,col,type_array[STOP],nearest_cost[row][col]));
			if(col-1 >= 0){
				edge[row][col][FLY_West].push_back(Edge(row,col-1,type_array[FLY_West],A));
			}
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			for(int a = 0; a < 5; a++){
				min_cost[row][col][a] = HUGE_NUM;
			}
		}
	}

	priority_queue<State> Q;
	min_cost[start.row][start.col][STOP] = 0;
	Q.push(State(start.row,start.col,STOP,0));
	LOC next_loc;
	Type next_type;

	while(!Q.empty()){

		if(Q.top().loc.row == goal.row && Q.top().loc.col == goal.col && Q.top().type == STOP){

			break;

		}else{

			for(int i = 0; i < edge[Q.top().loc.row][Q.top().loc.col][Q.top().type].size(); i++){

				next_loc = edge[Q.top().loc.row][Q.top().loc.col][Q.top().type][i].loc;
				next_cost = Q.top().sum_cost+edge[Q.top().loc.row][Q.top().loc.col][Q.top().type][i].cost;
				next_type = edge[Q.top().loc.row][Q.top().loc.col][Q.top().type][i].type;

				if(min_cost[next_loc.row][next_loc.col][next_type] > next_cost){

					min_cost[next_loc.row][next_loc.col][next_type] = next_cost;
					Q.push(State(next_loc.row,next_loc.col,next_type,next_cost));
				}
			}
			Q.pop();
		}
	}

	printf("%lld\n",min_cost[goal.row][goal.col][STOP]);

	return 0;
}
accuracy: 1
time_ms: 1650
memory_kb: 164888
final_rank: 16

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<unordered_map>
#define lol(i,n) for(int i=0;i<n;i++)
#define mod 1000000007
typedef long long ll;

using namespace std;
#define H 510
struct Ver{
    ll y,x,t;
    Ver(ll y,ll x,ll t){
	this->y=y,this->x=x,this->t=t;
    }
    bool operator<(const Ver&key)const{return 0;}
    bool operator>(const Ver&key)const{return 0;}
    bool operator==(const Ver&key)const{
	return this->y==key.y&&this->x==key.x&&this->t==key.t;
    }
    bool operator!=(const Ver&key)const{
	return !(this->operator==(key));
    }
    struct Hash{
	ll operator()(const Ver&key)const{
	    return key.t*H*H+key.y*H+key.x;
	}
    };
};
#define N 100010
ll h,w,a,b,c,n,s[N],t[N];
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
ll dis[H][H];
unordered_map<Ver,ll,Ver::Hash> d;
void Dijkstra(Ver s){
    typedef pair<ll,Ver> P;
    priority_queue<P,vector<P>,greater<P> >Q;
    Q.push(make_pair(0,s));
    while(!Q.empty()){
	ll cost=Q.top().first;
	Ver key=Q.top().second;
	Q.pop();
	ll i=key.y,j=key.x,t=key.t;
	if(i<0||i==h||j<0||j==w)continue;
	if(d.find(key)!=d.end())continue;
	d[key]=cost;
	lol(r,4){
	    int xx=j+dx[r],yy=i+dy[r];
	    if(t==4){
		Q.push(make_pair(cost+b,Ver(i,j,r)));
		Q.push(make_pair(cost+c,Ver(yy,xx,4)));
	    }
	    if(t==r){
		Q.push(make_pair(cost+dis[i][j]*c,Ver(i,j,4)));
		Q.push(make_pair(cost+a,Ver(yy,xx,r)));
	    }
	}
    }
}
void BFS(){
    lol(i,h)lol(j,w)dis[i][j]=mod;
    queue<Ver> Q;
    lol(i,n)Q.push(Ver(s[i],t[i],0));
    while(!Q.empty()){
	Ver key=Q.front();
	Q.pop();
	ll y=key.y,x=key.x,t=key.t;
	if(dis[y][x]<=t)continue;
	dis[y][x]=t;
	lol(r,4){
	    int xx=x+dx[r],yy=y+dy[r];
	    if(xx<0||xx==w||yy<0||yy==h)continue;
	    Q.push(Ver(yy,xx,t+1));
	}
    }
}
int main(){
    cin>>h>>w>>a>>b>>c>>n;h++,w++;
    lol(i,n)scanf("%lld%lld",&s[i],&t[i]);BFS();
    Dijkstra(Ver(s[0],t[0],4));
    cout<<d[Ver(s[n-1],t[n-1],4)]<<endl;
    return 0;
}
accuracy: 1
time_ms: 1760
memory_kb: 132492
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int D = 511;
const int di[4] = {-1, 0, 1, 0};
const int dj[4] = {0, -1, 0, 1};
const int BRING = 4;
const ll INF = 1LL<<60;

struct Ball {
    int i, j; char state;
    bool operator<(const Ball& o) const {
        return i != o.i ? i < o.i : j != o.j ? j < o.j : state < o.state;
    }
};

int bring[D][D];
ll dist[D][D][5];
int main() {
    int n, m, k;
    ll a, b, c;
    scanf("%d%d%lld%lld%lld%d", &n, &m, &a, &b, &c, &k);
    #define in_bounds(i,j) (0 <= (i) && (i) <= n && 0 <= (j) && (j) <= m)
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            bring[i][j] = n + m;
            for (int state = 0; state < 5; state++) {
                dist[i][j][state] = INF;
            }
        }
    }
    int bi = -1, bj = -1, ti, tj;
    vector<pair<int,int>> que;
    while (k--) {
        scanf("%d%d", &ti, &tj);
        if (!~bi) bi = ti, bj = tj;
        if (bring[ti][tj]) {
            bring[ti][tj] = 0;
            que.emplace_back(ti, tj);
        }
    }
    for (int f = 0; f < que.size(); f++) {
        int i, j;
        tie(i, j) = que[f];
        for (int d = 0; d < 4; d++) {
            int ni = i + di[d], nj = j + dj[d];
            if (in_bounds(ni, nj) && bring[ni][nj] > bring[i][j] + 1) {
                bring[ni][nj] = bring[i][j] + 1;
                que.emplace_back(ni, nj);
            }
        }
    }
    que.clear();

    typedef pair<ll,Ball> pear;
    priority_queue<pear, vector<pear>, greater<pear>> pq;
    pq.push({0LL, {bi, bj, BRING}});
    while (!pq.empty()) {
        ll dst;
        Ball x;
        tie(dst, x) = pq.top(); pq.pop();
        if (dist[x.i][x.j][x.state] <= dst) continue;
        if (x.i == ti && x.j == tj) {
            printf("%lld\n", dst);
            return 0;
        }
        dist[x.i][x.j][x.state] = dst;
        #define neighbor(d,i,j,state) do {\
            if (dist[i][j][state] > (d)) pq.push({(d), {(i), (j), (state)}});\
        } while (0)
        neighbor(dst + c * bring[x.i][x.j], x.i, x.j, BRING); // drop + walk
        if (x.state == BRING) {
            for (char d = 0; d < 4; d++) {
                int ni = x.i + di[d], nj = x.j + dj[d];
                if (in_bounds(ni, nj)) neighbor(dst + c, ni, nj, BRING); // bring
                neighbor(dst + b, x.i, x.j, d); // kick start
            }
        } else {
            int ni = x.i + di[x.state], nj = x.j + dj[x.state];
            if (in_bounds(ni, nj)) neighbor(dst + a, ni, nj, x.state); // kick go
        }
    }
}
accuracy: 1
time_ms: 310
memory_kb: 41836
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int D = 511;
const int di[4] = {-1, 0, 1, 0};
const int dj[4] = {0, -1, 0, 1};
const int DROP = 4;
const int BRING = 5;
const ll INF = 1LL<<60;

struct Ball {
    int i, j; char state;
    bool operator<(const Ball& o) const {
        return i != o.i ? i < o.i : j != o.j ? j < o.j : state < o.state;
    }
};

int bring[D][D];
ll dist[D][D][6];
int main() {
    int n, m, k;
    ll a, b, c;
    scanf("%d%d%lld%lld%lld%d", &n, &m, &a, &b, &c, &k);
    #define in_bounds(i,j) (0 <= (i) && (i) <= n && 0 <= (j) && (j) <= m)
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            bring[i][j] = n + m;
            for (int state = 0; state < 6; state++) {
                dist[i][j][state] = INF;
            }
        }
    }
    int bi = -1, bj = -1, ti, tj;
    vector<pair<int,int>> que;
    while (k--) {
        scanf("%d%d", &ti, &tj);
        if (!~bi) bi = ti, bj = tj;
        if (bring[ti][tj]) {
            bring[ti][tj] = 0;
            que.emplace_back(ti, tj);
        }
    }
    for (int f = 0; f < que.size(); f++) {
        int i, j;
        tie(i, j) = que[f];
        for (int d = 0; d < 4; d++) {
            int ni = i + di[d], nj = j + dj[d];
            if (in_bounds(ni, nj) && bring[ni][nj] > bring[i][j] + 1) {
                bring[ni][nj] = bring[i][j] + 1;
                que.emplace_back(ni, nj);
            }
        }
    }
    que.clear();

    typedef pair<ll,Ball> pear;
    priority_queue<pear, vector<pear>, greater<pear>> pq;
    pq.push({0LL, {bi, bj, DROP}});
    while (!pq.empty()) {
        ll dst;
        Ball x;
        tie(dst, x) = pq.top(); pq.pop();
        if (dist[x.i][x.j][x.state] <= dst) continue;
        if (x.i == ti && x.j == tj) {
            printf("%lld\n", dst);
            return 0;
        }
        dist[x.i][x.j][x.state] = dst;
        #define neighbor(d,i,j,state) do {\
            if (dist[i][j][state] > (d)) pq.push({(d), {(i), (j), (state)}});\
        } while (0)
        neighbor(dst + 0LL, x.i, x.j, DROP); // drop
        if (x.state == DROP) { // walk to
            neighbor(dst + c * bring[x.i][x.j], x.i, x.j, BRING);
        } else if (x.state == BRING) {
            for (char d = 0; d < 4; d++) {
                int ni = x.i + di[d], nj = x.j + dj[d];
                if (in_bounds(ni, nj)) neighbor(dst + c, ni, nj, BRING); // bring
                neighbor(dst + b, x.i, x.j, d); // kick start
            }
        } else {
            int ni = x.i + di[x.state], nj = x.j + dj[x.state];
            if (in_bounds(ni, nj)) neighbor(dst + a, ni, nj, x.state); // kick go
        }
    }
}
accuracy: 1
time_ms: 300
memory_kb: 25500
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int D = 511;
const int di[4] = {-1, 0, 1, 0};
const int dj[4] = {0, -1, 0, 1};
const int DROP = -2;
const int BRING = -1;
struct Ball;
typedef pair<ll,Ball> pear;

int n, m;
ll a, b, c;
inline bool in_bounds(int i, int j) {
    return 0 <= i && i <= n && 0 <= j && j <= m;
}

ll dsts[D][D];
int ti, tj;
struct Ball {
    int i, j, state;
    bool operator<(const Ball& o) const {
        if (i != o.i) return i < o.i;
        if (j != o.j) return j < o.j;
        return state < o.state;
    }
    bool operator==(const Ball& o) const {
        return i == o.i && j == o.j && state == o.state;
    }
    bool is_end() {
        return i == ti && j == tj;
    }
    vector<pear> adj() {
        vector<pear> res;
        // drop
        res.push_back({0LL, {i, j, DROP}});
        if (state == DROP) {
            // walk to
            res.push_back({c * dsts[i][j], {i, j, BRING}});
        } else if (state == BRING) {
            for (int d = 0; d < 4; d++) {
                int ni = i + di[d];
                int nj = j + dj[d];
                // bring
                if (in_bounds(ni, nj)) {
                    res.push_back({c, {ni, nj, BRING}});
                }
                // kick start
                res.push_back({b, {i, j, d}});
            }
        } else {// kick
            int ni = i + di[state];
            int nj = j + dj[state];
            if (in_bounds(ni, nj)) {
                res.push_back({a, {ni, nj, state}});
            }
        }
        return res;
    }
};

void solve() {
    int k;
    if (scanf("%d%d%lld%lld%lld%d", &n, &m, &a, &b, &c, &k) != 6) exit(0);
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            dsts[i][j] = n + m;
        }
    }
    int bi = -1, bj = -1;
    vector<pair<int,int>> que;
    while (k--) {
        scanf("%d%d", &ti, &tj);
        if (!~bi) bi = ti, bj = tj;
        if (dsts[ti][tj]) {
            dsts[ti][tj] = 0;
            que.emplace_back(ti, tj);
        }
    }
    for (int f = 0; f < que.size(); f++) {
        int i, j;
        tie(i, j) = que[f];
        for (int d = 0; d < 4; d++) {
            int ni = i + di[d];
            int nj = j + dj[d];
            if (in_bounds(ni, nj) && dsts[ni][nj] > dsts[i][j] + 1) {
                dsts[ni][nj] = dsts[i][j] + 1;
                que.emplace_back(ni, nj);
            }
        }
    }

    priority_queue<pear, vector<pear>, greater<pear>> pq;
    pq.push({0LL, {bi, bj, DROP}});
    map<Ball,ll> dit;
    while (!pq.empty()) {
        ll d;
        Ball i;
        tie(d, i) = pq.top(); pq.pop();
        if (dit.count(i)) continue;
        if (i.is_end()) {
            printf("%lld\n", d);
            return;
        }
        dit[i] = d;
        for (auto nb : i.adj()) {
            if (!dit.count(nb.second)) {
                pq.emplace(d + nb.first, nb.second);
            }
        }
    }
    assert(false);
}

int main() {
    while (true) solve();
}
accuracy: 1
time_ms: 1620
memory_kb: 100028
final_rank: 14

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

#define REP(i, a, b) for (int(i) = int(a); (i) <= int(b); (i)++)
#define F first
#define S second
typedef long long ll;
typedef pair<int, int> ii;

#define H 511
ll h, w, a, b, c, n, sx, sy, s, t, tx, ty, res;
ll dist[H][H], dp[H][H][5];
queue<pair<ii, int>> q;

int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};

void solve(int i, int j, int st) {
  //cout << i << ' ' << j << ' ' << st << ' ' << dp[i][j][st] << endl;
  if (st == 0) { // if i am being dribbled
    REP(k, 1, 4) { // in any direction
      int I = i+dx[k-1], J = j+dy[k-1];
      if (0 > I || I > h || 0 > J || J > w) continue;
      // i could continue being dribbled
      if (dp[i][j][0] + c < dp[I][J][0]) {
        dp[I][J][0] = dp[i][j][0] + c;
        //cout << "    " << I << ' ' << J << ' ' << 0 << ' ' << dp[I][J][0] << endl;
        q.emplace(ii(I, J), 0);
      }
      // i could be kicked
      if (dp[i][j][0] + a + b < dp[I][J][k]) {
        dp[I][J][k] = dp[i][j][0] + a + b;
        //cout << "    " << I << ' ' << J << ' ' << k << ' ' << dp[I][J][k] << endl;
        q.emplace(ii(I, J), k);
      }
    }
  } else { // if i am being kicked
    // i could keep going in the same direction
    int k = st;
    int I = i+dx[k-1], J = j+dy[k-1];
    if (0 <= I && I <= h && 0 <= J && J <= w && dp[i][j][k] + a < dp[I][J][k]) {
      dp[I][J][k] = dp[i][j][k] + a;
        //cout << "    " << I << ' ' << J << ' ' << k << ' ' << dp[I][J][k] << endl;
      q.emplace(ii(I, J), k);
    }
    // someone could catch me
    if (dp[i][j][k] + c * dist[i][j] < dp[i][j][0]) {
      dp[i][j][0] = dp[i][j][k] + c * dist[i][j];
        //cout << "    " << i << ' ' << j << ' ' << 0 << ' ' << dp[i][j][0] << endl;
      q.emplace(ii(i, j), 0);
    }
  }
}

int main() {
  ios_base::sync_with_stdio(0);
  cin >> h >> w >> a >> b >> c >> n;
  memset(dist, -1, sizeof(dist));
  memset(dp, 63, sizeof(dp));
  cin >> sx >> sy;
  dist[sx][sy] = 0;
  q.emplace(ii(sx, sy), 0);
  REP(i, 2, n-1) {
    cin >> s >> t;
    dist[s][t] = 0;
    q.emplace(ii(s, t), 0);
  }
  cin >> tx >> ty;
  while (!q.empty()) {
    int x = q.front().F.F, y = q.front().F.S; q.pop();
    REP(k, 0, 3) {
      int X = x+dx[k], Y = y+dy[k];
      if (0 <= X && X <= h && 0 <= Y && Y <= w && !~dist[X][Y]) {
        dist[X][Y] = dist[x][y] + 1;
        q.emplace(ii(X, Y), 0);
      }
    }
  }

  // REP(i, 0, h) {
  //   REP(j, 0, w) cout << dist[i][j] << ' ';
  //   cout << endl;
  // }

  dp[sx][sy][0] = 0;
  q.emplace(ii(sx, sy), 0);
  while (!q.empty()) {
    solve(q.front().F.F, q.front().F.S, q.front().S);
    q.pop();
  }
  res = 0x3f3f3f3f;
  REP(k, 0, 5) res = min(res, dp[tx][ty][k]);
  cout << res << endl;
}
accuracy: 0.15384615384615385
time_ms: 40
memory_kb: 15424
final_rank: 17

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<functional>
#define PAIR pair<int,int>
using namespace std;
class point{
public:
    vector<long long> dp;
    long long fast;
    point(){
        dp.resize(5,((long long)1<<63)-1);
        fast = 10000000;
    }
};
int H,W;
long long A,B,C,N;
vector<PAIR> mv;
class num{
public:
    long long time;
    PAIR pos;
    int dir;
};

bool operator<(const num&A,const num&B){
    return A.time<B.time;
}
bool operator>(const num&A,const num&B){
    return A.time>B.time;
}
bool operator==(const num&A,const num&B){
    return A.time==B.time;
}

PAIR operator + (const PAIR&A,const PAIR&B){
    PAIR res;
    res.first = A.first+B.first;
    res.second = A.second+B.second;
    return res;
}

point& getpa(vector<vector<point> >&map,PAIR d){
    int x =d.first;
    int y = d.second;
    return map[x][y];
}

void getfast(vector<vector<point> >&,vector<PAIR>&);
bool isin(int,int);
int main(){
    mv.resize(5);
    mv[0]=PAIR(1,0);
    mv[1]=PAIR(0,-1);
    mv[2]=PAIR(-1,0);
    mv[3]=PAIR(0,1);
    mv[4]=PAIR(0,0);
    cin>>H>>W>>A>>B>>C>>N;
    vector<vector<point> > map(W+1,vector<point>(H+1));
    vector<PAIR> player(N);
    for(int i=0;i<N;++i){
        cin>>player[i].second>>player[i].first;
    }
    getfast(map,player);
    priority_queue<num,vector<num>,greater<num> > que;
    getpa(map,player[0]).dp[4]=0;
    num start;
    start.time = 0;
    start.pos = player[0];
    start.dir = 4;
    /*
    for(int y=0;y<map.front().size();++y){
        for(int x=0;x<map.size();++x){
            cout<<map[x][y].dp[4]<<" ";
        }
        cout<<endl;
    }
     */
    que.push(start);
    while(!que.empty()){
        num d = que.top();
        que.pop();
        if(d.time!=getpa(map,d.pos).dp[d.dir]){
            continue;
        }
        if(d.dir<4){
            PAIR np = d.pos + mv[d.dir];
            if(isin(np.first,np.second)){
                long long ntime = d.time + A;
                if(ntime<getpa(map,np).dp[d.dir]){
                    getpa(map,np).dp[d.dir] = ntime;
                    num dnum;
                    dnum.time = ntime;
                    dnum.pos = np;
                    dnum.dir = d.dir;
                    que.push(dnum);
                }
            }
            long long ntime = d.time + getpa(map,d.pos).fast;
            if(ntime<getpa(map,d.pos).dp[4]){
                getpa(map,d.pos).dp[4] = ntime;
                num dnum;
                dnum.time = ntime;
                dnum.pos = d.pos;
                dnum.dir = 4;
                que.push(dnum);
            }
        }else{
            for(int i=0;i<4;++i){
                long long ntime = d.time + B;
                if(ntime<getpa(map,d.pos).dp[i]){
                    getpa(map,d.pos).dp[i]=ntime;
                    num dnum;
                    dnum.time = ntime;
                    dnum.pos = d.pos;
                    dnum.dir = i;
                    que.push(dnum);
                }
                ntime = d.time + C;
                PAIR np = d.pos + mv[i];
                if(!isin(np.first,np.second)){
                    continue;
                }
                if(ntime<getpa(map,np).dp[4]){
                    getpa(map,np).dp[4]=ntime;
                    num dnum;
                    dnum.time = ntime;
                    dnum.pos = np;
                    dnum.dir = 4;
                    que.push(dnum);
                }
            }
        }
    }
    cout<<getpa(map,player.back()).dp[4]<<endl;
    
    /*
    for(int y=0;y<map.front().size();++y){
        for(int x=0;x<map.size();++x){
            cout<<map[x][y].dp[4]<<" ";
        }
        cout<<endl;
    }
     */
    return 0;
}

void getfast(vector<vector<point> >& map,vector<PAIR>&player){
    queue<PAIR> que;
    for(int i=0;i<player.size();++i){
        int x = player[i].first;
        int y = player[i].second;
        que.push(player[i]);
        getpa(map,player[i]).fast=0;
    }
    while(!que.empty()){
        PAIR d = que.front();
        que.pop();
        for(int i=0;i<4;++i){
            PAIR np = d+mv[i];
            if(!isin(np.first,np.second)){
                continue;
            }
            if(getpa(map,np).fast>getpa(map,d).fast+1){
                getpa(map,np).fast = getpa(map,d).fast+1;
                que.push(np);
            }
        }
    }
    for(int x=0;x<map.size();++x){
        for(int y=0;y<map.front().size();++y){
            getpa(map,PAIR(x,y)).fast*=C;
        }
    }
}

bool isin(int x,int y){
    return x>=0&&x<=W&&y>=0&&y<=H;
}
accuracy: 1
time_ms: 380
memory_kb: 29520
final_rank: 9

code_snippet: #include <queue>
#include <vector>
#include <iostream>
using namespace std;
typedef long long ll;
struct edge { int to; ll cost; };
struct state { int pos; ll cost; };
bool operator<(const state& s1, const state& s2) { return s1.cost > s2.cost; }
int dx[] = { 0, 1, 0, -1 };
int dy[] = { 1, 0, -1, 0 };
int H, W, A, B, C, N, x[100009], y[100009], xl[100009], xr[100009], yl[100009], yr[100009], ds[509][509]; vector<vector<edge> > g;
void add_edge(int v1, int v2, ll c) {
	g[v1].push_back(edge{ v2, c });
}
void add_edge2(int v1, int v2, ll c) {
	add_edge(v1, v2, c);
	add_edge(v2, v1, c);
}
ll shortest_path(int start, int goal) {
	vector<ll> dist(g.size(), 1LL << 60); dist[start] = 0;
	priority_queue<state> que; que.push(state{ start, 0 });
	while (!que.empty()) {
		int u = que.top().pos; que.pop();
		for (edge e : g[u]) {
			ll nd = dist[u] + e.cost;
			if (dist[e.to] > nd) {
				dist[e.to] = nd;
				que.push(state{ e.to, nd });
			}
		}
	}
	return dist[goal];
}
int main() {
	ios::sync_with_stdio(false);
	cin >> H >> W >> A >> B >> C >> N; H++; W++;
	g.resize(3 * H * W);
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (j >= 1) {
				add_edge2(i * W + j, i * W + j - 1, C);
				add_edge2(H * W + i * W + j, H * W + i * W + j - 1, A);
			}
			if (i >= 1) {
				add_edge2(i * W + j, i * W + j - W, C);
				add_edge2(2 * H * W + i * W + j, 2 * H * W + i * W + j - W, A);
			}
			add_edge(i * W + j, H * W + i * W + j, B);
			add_edge(i * W + j, 2 * H * W + i * W + j, B);
			ds[i][j] = -1;
		}
	}
	fill(xl, xl + H, W + 1);
	fill(xr, xr + H, -1);
	fill(yl, yl + W, H + 1);
	fill(yr, yr + W, -1);
	queue<pair<int, int> > qs;
	for (int i = 0; i < N; i++) {
		cin >> x[i] >> y[i];
		xl[x[i]] = min(xl[x[i]], y[i]);
		xr[x[i]] = max(xr[x[i]], y[i]);
		yl[y[i]] = min(yl[y[i]], x[i]);
		yr[y[i]] = max(yr[y[i]], x[i]);
		ds[x[i]][y[i]] = 0;
		add_edge(H * W + x[i] * W + y[i], x[i] * W + y[i], 0);
		add_edge(2 * H * W + x[i] * W + y[i], x[i] * W + y[i], 0);
		qs.push(make_pair(x[i], y[i]));
	}
	while (!qs.empty()) {
		pair<int, int> u = qs.front(); qs.pop();
		for (int i = 0; i < 4; i++) {
			int px = u.first + dx[i], py = u.second + dy[i];
			if (0 <= px && px < H && 0 <= py && py < W && ds[px][py] == -1) {
				ds[px][py] = ds[u.first][u.second] + 1;
				add_edge(H * W + px * W + py, px * W + py, 1LL * ds[px][py] * C);
				add_edge(2 * H * W + px * W + py, px * W + py, 1LL * ds[px][py] * C);
				qs.push(make_pair(px, py));
			}
		}
	}
	cout << shortest_path(x[0] * W + y[0], x[N - 1] * W + y[N - 1]) << '\n';
	return 0;
}
accuracy: 1
time_ms: 590
memory_kb: 115452
final_rank: 13

code_snippet: #include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <functional>
#include <tuple>
using namespace std;
long long H, W, A, B, C, N, x[100009], y[100009], dist[509][509][4], dp[509][509], dx[4] = { 0,1,0,-1 }, dy[4] = { 1,0,-1,0 };
priority_queue<tuple<long long, int, int>, vector<tuple<long long, int, int>>, greater<tuple<long long, int, int>>>q;
priority_queue<tuple<long long, int, int, int>, vector<tuple<long long, int, int, int>>, greater<tuple<long long, int, int, int>>>Q;
int main() {
	cin >> H >> W >> A >> B >> C >> N;
	for (int i = 0; i <= H; i++) { for (int j = 0; j <= W; j++)dp[i][j] = (1LL << 62); }
	for (int i = 1; i <= N; i++) { cin >> x[i] >> y[i]; if (i < N) dp[x[i]][y[i]] = 0; q.push(make_tuple(0, x[i], y[i])); }
	while (!q.empty()) {
		long long a1 = get<0>(q.top()), a2 = get<1>(q.top()), a3 = get<2>(q.top()); q.pop();
		for (int i = 0; i < 4; i++) {
			int cx = a2 + dx[i], cy = a3 + dy[i];
			if (cx < 0 || cx > H || cy < 0 || cy > W)continue;
			if (dp[cx][cy] > a1 + C) {
				dp[cx][cy] = a1 + C; q.push(make_tuple(dp[cx][cy], cx, cy));
			}
		}
	}
	for (int i = 0; i <= H; i++) { for (int j = 0; j <= W; j++) { for (int k = 0; k < 4; k++)dist[i][j][k] = (1LL << 62); } }
	dist[x[1]][y[1]][1] = 0; Q.push(make_tuple(0LL, x[1], y[1], 1));
	while (!Q.empty()) {
		long long a1 = get<0>(Q.top()), a2 = get<1>(Q.top()), a3 = get<2>(Q.top()), a4 = get<3>(Q.top()); Q.pop();
		if (a4 == 0) {
			if (dist[a2][a3][1] > a1 + dp[a2][a3]) { dist[a2][a3][1] = a1 + dp[a2][a3]; Q.push(make_tuple(dist[a2][a3][1], a2, a3, 1)); }
		}
		if (a4 == 1) {
			if (dist[a2][a3][2] > a1 + B) { dist[a2][a3][2] = a1 + B; Q.push(make_tuple(dist[a2][a3][2], a2, a3, 2)); }
			if (dist[a2][a3][3] > a1 + B) { dist[a2][a3][3] = a1 + B; Q.push(make_tuple(dist[a2][a3][3], a2, a3, 3)); }
			if (a2 - 1 >= 0 && dist[a2 - 1][a3][1] > a1 + C) { dist[a2 - 1][a3][1] = a1 + C; Q.push(make_tuple(dist[a2 - 1][a3][1], a2 - 1, a3, 1)); }
			if (a2 + 1 <= H && dist[a2 + 1][a3][1] > a1 + C) { dist[a2 + 1][a3][1] = a1 + C; Q.push(make_tuple(dist[a2 + 1][a3][1], a2 + 1, a3, 1)); }
			if (a3 - 1 >= 0 && dist[a2][a3 - 1][1] > a1 + C) { dist[a2][a3 - 1][1] = a1 + C; Q.push(make_tuple(dist[a2][a3 - 1][1], a2, a3 - 1, 1)); }
			if (a3 + 1 <= W && dist[a2][a3 + 1][1] > a1 + C) { dist[a2][a3 + 1][1] = a1 + C; Q.push(make_tuple(dist[a2][a3 + 1][1], a2, a3 + 1, 1)); }
			if (dist[a2][a3][0] > a1) { dist[a2][a3][0] = a1; Q.push(make_tuple(dist[a2][a3][0], a2, a3, 0)); }
		}
		if (a4 == 2) {
			if (a2 - 1 >= 0 && dist[a2 - 1][a3][2] > a1 + A) { dist[a2 - 1][a3][2] = a1 + A; Q.push(make_tuple(dist[a2 - 1][a3][2], a2 - 1, a3, 2)); }
			if (a2 + 1 <= H && dist[a2 + 1][a3][2] > a1 + A) { dist[a2 + 1][a3][2] = a1 + A; Q.push(make_tuple(dist[a2 + 1][a3][2], a2 + 1, a3, 2)); }
			if (dist[a2][a3][0] > a1) { dist[a2][a3][0] = a1; Q.push(make_tuple(dist[a2][a3][0], a2, a3, 0)); }
		}
		if (a4 == 3) {
			if (a3 - 1 >= 0 && dist[a2][a3 - 1][3] > a1 + A) { dist[a2][a3 - 1][3] = a1 + A; Q.push(make_tuple(dist[a2][a3 - 1][3], a2, a3 - 1, 3)); }
			if (a3 + 1 <= W && dist[a2][a3 + 1][3] > a1 + A) { dist[a2][a3 + 1][3] = a1 + A; Q.push(make_tuple(dist[a2][a3 + 1][3], a2, a3 + 1, 3)); }
			if (dist[a2][a3][0] > a1) { dist[a2][a3][0] = a1; Q.push(make_tuple(dist[a2][a3][0], a2, a3, 0)); }
		}
	}
	cout << dist[x[N]][y[N]][0] << endl;
	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 23552
final_rank: 5

code_snippet: #include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <functional>
#include <tuple>
using namespace std;
long long H, W, A, B, C, N, x[100009], y[100009], dist[509][509][4], dp[509][509], dx[4] = { 0,1,0,-1 }, dy[4] = { 1,0,-1,0 };
priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>>q;
priority_queue<tuple<long long, int, int, int>, vector<tuple<long long, int, int, int>>, greater<tuple<long long, int, int, int>>>Q;
int main() {
	cin >> H >> W >> A >> B >> C >> N;
	for (int i = 0; i <= H; i++) { for (int j = 0; j <= W; j++)dp[i][j] = 999999999; }
	for (int i = 1; i <= N; i++) { cin >> x[i] >> y[i]; if (i < N) dp[x[i]][y[i]] = 0; q.push(make_tuple(0, x[i], y[i])); }
	while (!q.empty()) {
		int a1 = get<0>(q.top()), a2 = get<1>(q.top()), a3 = get<2>(q.top()); q.pop();
		for (int i = 0; i < 4; i++) {
			int cx = a2 + dx[i], cy = a3 + dy[i];
			if (cx < 0 || cx > H || cy < 0 || cy > W)continue;
			if (dp[cx][cy] > a1 + C) {
				dp[cx][cy] = a1 + C; q.push(make_tuple(dp[cx][cy], cx, cy));
			}
		}
	}
	for (int i = 0; i <= H; i++) { for (int j = 0; j <= W; j++) { for (int k = 0; k < 4; k++)dist[i][j][k] = (1LL << 62); } }
	dist[x[1]][y[1]][1] = 0; Q.push(make_tuple(0LL, x[1], y[1], 1));
	while (!Q.empty()) {
		int a1 = get<0>(Q.top()), a2 = get<1>(Q.top()), a3 = get<2>(Q.top()), a4 = get<3>(Q.top()); Q.pop();
		if (a4 == 0) {
			if (dist[a2][a3][1] > a1 + dp[a2][a3]) { dist[a2][a3][1] = a1 + dp[a2][a3]; Q.push(make_tuple(dist[a2][a3][1], a2, a3, 1)); }
		}
		if (a4 == 1) {
			if (dist[a2][a3][2] > a1 + B) { dist[a2][a3][2] = a1 + B; Q.push(make_tuple(dist[a2][a3][2], a2, a3, 2)); }
			if (dist[a2][a3][3] > a1 + B) { dist[a2][a3][3] = a1 + B; Q.push(make_tuple(dist[a2][a3][3], a2, a3, 3)); }
			if (a2 - 1 >= 0 && dist[a2 - 1][a3][1] > a1 + C) { dist[a2 - 1][a3][1] = a1 + C; Q.push(make_tuple(dist[a2 - 1][a3][1], a2 - 1, a3, 1)); }
			if (a2 + 1 <= H && dist[a2 + 1][a3][1] > a1 + C) { dist[a2 + 1][a3][1] = a1 + C; Q.push(make_tuple(dist[a2 + 1][a3][1], a2 + 1, a3, 1)); }
			if (a3 - 1 >= 0 && dist[a2][a3 - 1][1] > a1 + C) { dist[a2][a3 - 1][1] = a1 + C; Q.push(make_tuple(dist[a2][a3 - 1][1], a2, a3 - 1, 1)); }
			if (a3 + 1 <= W && dist[a2][a3 + 1][1] > a1 + C) { dist[a2][a3 + 1][1] = a1 + C; Q.push(make_tuple(dist[a2][a3 + 1][1], a2, a3 + 1, 1)); }
			if (dist[a2][a3][0] > a1) { dist[a2][a3][0] = a1; Q.push(make_tuple(dist[a2][a3][0], a2, a3, 0)); }
		}
		if (a4 == 2) {
			if (a2 - 1 >= 0 && dist[a2 - 1][a3][2] > a1 + A) { dist[a2 - 1][a3][2] = a1 + A; Q.push(make_tuple(dist[a2 - 1][a3][2], a2 - 1, a3, 2)); }
			if (a2 + 1 <= H && dist[a2 + 1][a3][2] > a1 + A) { dist[a2 + 1][a3][2] = a1 + A; Q.push(make_tuple(dist[a2 + 1][a3][2], a2 + 1, a3, 2)); }
			if (dist[a2][a3][0] > a1) { dist[a2][a3][0] = a1; Q.push(make_tuple(dist[a2][a3][0], a2, a3, 0)); }
		}
		if (a4 == 3) {
			if (a3 - 1 >= 0 && dist[a2][a3 - 1][3] > a1 + A) { dist[a2][a3 - 1][3] = a1 + A; Q.push(make_tuple(dist[a2][a3 - 1][3], a2, a3 - 1, 3)); }
			if (a3 + 1 <= W && dist[a2][a3 + 1][3] > a1 + A) { dist[a2][a3 + 1][3] = a1 + A; Q.push(make_tuple(dist[a2][a3 + 1][3], a2, a3 + 1, 3)); }
			if (dist[a2][a3][0] > a1) { dist[a2][a3][0] = a1; Q.push(make_tuple(dist[a2][a3][0], a2, a3, 0)); }
		}
	}
	cout << dist[x[N]][y[N]][0] << endl;
	return 0;
}
accuracy: 0.15384615384615385
time_ms: 130
memory_kb: 18968
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#define ll long long
using namespace std;
typedef pair<ll,int> ii;
#define fi first
#define se second
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};
ll A,B,C;
int n,h,w;
ll dp0[505][505], dp1[505][505][4];
bool player[505][505];
int min_distance[505][505];
void prep(){
	queue <int> q;
	for(int i=0;i<=h;i++)
		for(int j=0;j<=w;j++){
			if (player[i][j]) min_distance[i][j] = 0, q.push(i * 501 + j);
			else min_distance[i][j] = 100000;
		}
	while(q.size()){
		int x = q.front() / 501;
		int y = q.front() % 501;
		q.pop();
		for(int k=0;k<4;k++){
			int X = x + dx[k];
			int Y = y + dy[k];
			if (0 > X || X > h || 0 > Y || Y > w) continue;
			if (min_distance[X][Y] > min_distance[x][y] + 1)
				min_distance[X][Y] = min_distance[x][y] + 1,
				q.push(X * 501 + Y);
		}
	}
}
#define x1 asd
#define y1 jnda
#define xn addaf
#define yn nln
int x1,y1,xn,yn;
void prep_dp(){
	for(int i=0;i<=h;i++)
		for(int j=0;j<=w;j++)
			dp0[i][j] = dp1[i][j][0] = dp1[i][j][1] = dp1[i][j][2] = dp1[i][j][3] = (ll) 1e18;
	dp0[x1][y1] = 0;
}
bool  markh[505], markw[505];
 
void cal_dp(){
	priority_queue <ii,vector<ii>,greater<ii> > pq;
	
	pq.push(ii(0, x1 * 3500 + y1 * 5));
		
	while(pq.size()){
		int x = pq.top().se / 3500;
		int y = (pq.top().se % 3500) / 5;
		int type = pq.top().se % 5;
		ll dis = pq.top().fi;
		pq.pop();
		
		if (type == 0 && dp0[x][y] != dis) continue;
		if (type && dp1[x][y][type-1] != dis) continue;
		
		if (type == 0){
			for(int k=0;k<4;k++){
				int X = x + dx[k];
				int Y = y + dy[k];
				if (0 > X || X > h || 0 > Y || Y > w) continue;
				if (dp1[X][Y][k] > dp0[x][y] + A + B)
					dp1[X][Y][k] = dp0[x][y] + A + B,
					pq.push(ii(dp1[X][Y][k], X * 3500 + Y * 5 + k+1));
					
				if (dp0[X][Y] > dp0[x][y] + C)
					dp0[X][Y] = dp0[x][y] + C,
					pq.push(ii(dp0[X][Y], X * 3500 + Y * 5 + 0));
			}
		}
		else{
			int X = x + dx[type-1];
			int Y = y + dy[type-1];
			if (dp1[x][y][type-1] + min_distance[x][y] * C < dp0[x][y])
				dp0[x][y] = dp1[x][y][type-1] + min_distance[x][y] * C,
				pq.push(ii(dp0[x][y], x*3500 + y*5));
			if (0 > X || X > h || 0 > Y || Y > w) continue;
			if (dp1[X][Y][type-1] > dp1[x][y][type-1] + A)
				dp1[X][Y][type-1] = dp1[x][y][type-1] + A,
				pq.push(ii(dp1[X][Y][type-1], X * 3500 + Y * 5 + type));
			
		}
	}
}
int main(){
	iostream::sync_with_stdio(0);
	cin >> h >> w;
	cin >> A >> B >> C;
	cin >> n;
	for(int i=1;i<=n;i++){
		int x,y;
		cin >> x >> y; 
		if (i == 1) x1 = x, y1 = y;
		if (i == n) xn = x, yn = y;
		player[x][y] = 1;
	}
	prep();
	prep_dp();
	cal_dp();
	cout << dp0[xn][yn] << endl;
}
accuracy: 1
time_ms: 250
memory_kb: 18216
final_rank: 3

code_snippet: #include <cstdio>
#include <queue>
#include <algorithm>
#define X_MAX 500
#define Y_MAX 500
#define N_MAX 100000
#define V_MAX ((X_MAX + 1) * (Y_MAX + 1))
#define lld "%lld"
typedef long long lnt;
typedef bool bnt;
typedef void vnt;
const lnt LNF = 0x3F3F3F3F3F3F3FLL;
const int dx[] = {-1, 0, +1, 0}, dy[] = {0, -1, 0, +1};
int X, Y, N, i, k, x, y, u, v, sx, sy, tx, ty, Ql = -1, Qr = -1, Q[V_MAX * 2];
lnt A, B, C, dir[X_MAX + 1][Y_MAX + 1], dis[X_MAX + 1][Y_MAX + 1][3];
inline bnt chk(int x, int y) { return x >= 0 && x <= X && y >= 0 && y <= Y; }
struct dat
{
	int k, x, y; lnt d;
	bnt operator < (const dat & p) const { return d > p.d; }
} p;
std::priority_queue<dat> P;
int main()
{
	scanf("%d %d" lld lld lld "%d", &X, &Y, &A, &B, &C, &N);
	for (x = 0; x <= X; ++x)
		for (y = 0; y <= Y; ++y)
			dir[x][y] = -1;
	scanf("%d %d", &sx, &sy), dir[sx][sy] = 0;
	for (i = 2; i < N; ++i)
		scanf("%d %d", &x, &y), dir[x][y] = 0;
	scanf("%d %d", &tx, &ty), dir[tx][ty] = 0;
	for (x = 0; x <= X; ++x)
		for (y = 0; y <= Y; ++y)
			if (!dir[x][y])
				Q[++Qr] = x, Q[++Qr] = y;
	while (Ql < Qr)
	{
		x = Q[++Ql], y = Q[++Ql];
		for (k = 0; k < 4; ++k)
			if (chk(u = x + dx[k], v = y + dy[k]) && !~dir[u][v])
				dir[u][v] = dir[x][y] + C, Q[++Qr] = u, Q[++Qr] = v;
	}
	for (k = 0; k < 3; ++k)
		for (x = 0; x <= X; ++x)
			for (y = 0; y <= Y; ++y)
				dis[x][y][k] = LNF;
	P.push((dat) {2, sx, sy, 0});
	while (true)
	{
		p = P.top(), P.pop();
		if (dis[p.x][p.y][p.k] < LNF)
			continue;
		if (p.x == tx && p.y == ty)
			break;
		dis[p.x][p.y][p.k] = p.d;
		switch (p.k)
		{
		case 2:
			for (k = 0; k < 2; ++k)
				if (dis[p.x][p.y][k] == LNF)
					P.push((dat) {k, p.x, p.y, p.d + B});
			for (k = 0; k < 4; ++k)
				if (chk(u = p.x + dx[k], v = p.y + dy[k]) && dis[u][v][2] == LNF)
					P.push((dat) {p.k, u, v, p.d + C});
			break;
		default:
			if (dis[p.x][p.y][2] == LNF)
				P.push((dat) {2, p.x, p.y, p.d + dir[p.x][p.y]});
			for (k = p.k; k < 4; k += 2)
				if (chk(u = p.x + dx[k], v = p.y + dy[k]) && dis[u][v][p.k] == LNF)
					P.push((dat) {p.k, u, v, p.d + A});
		}
	}
	printf(lld "\n", p.d);
	return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 24476
final_rank: 4