ferinの競プロ帳

競プロについてのメモ

AOJ 0596 Taxis

問題ページ
タクシー | Aizu Online Judge

考えたこと

最短距離と言われたのでdijkstraを考える。遷移先が距離r[i]以下の頂点であるdijkstraをすればよさそう。全頂点からそれぞれdijkstraをしてある頂点から距離がr[i]以下の点を全列挙しておけば、あとはdijkstraでよさそう。前処理にO(EVlogV)で大体1*10^8くらいになりそうだけどTLが8secで緩いのでこれでも通りそうと思い投げたら通った。

//#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VL;
typedef vector<VL> VVL;
typedef pair<int, int> PII;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define IN(a, b, x) (a<=x&&x<b)
#define MP make_pair
#define PB push_back
const int INF = (1LL<<30);
const ll LLINF = (1LL<<60);
const double PI = 3.14159265359;
const double EPS = 1e-12;
const int MOD = 1000000007;
//#define int ll

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }

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

int c[5010], r[5010];

struct edge{int to, cost;};

int n, d[5010];
vector<edge> g[5010];
VI v[5010];

void dijkstra(int s) {
  priority_queue<PII, vector<PII>, greater<PII>> que;
  fill(d, d+n, INF);
  d[s] = 0;
  que.push(PII{0, s});

  while(que.size()) {
    PII p = que.top(); que.pop();
    int v = p.second;
    if(d[v] < p.first) continue;
    for(edge e: g[v]) {
      if(d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(PII{d[e.to], e.to});
      }
    }
  }
  REP(i, n) if(d[i] <= r[s]) v[s].PB(i);
}

void dijkstra2(int s) {
  priority_queue<PII, vector<PII>, greater<PII>> que;
  fill(d, d+n, INF);
  d[s] = 0;
  que.push(PII{0, s});

  while(que.size()) {
    PII p = que.top(); que.pop();
    int vv = p.second;
    if(d[vv] < p.first) continue;
    for(int i: v[vv]) {
      if(d[i] > d[vv] + c[vv]) {
        d[i] = d[vv] + c[vv];
        que.push(PII{d[i], i});
      }
    }
  }
  cout << d[n-1] << endl;
}

signed main(void)
{
  int k;
  cin >> n >> k;
  REP(i, n) cin >> c[i] >> r[i];
  REP(i, k) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    g[x].PB({y, 1});
    g[y].PB({x, 1});
  }

  REP(i, n) dijkstra(i);
  dijkstra2(0);

  return 0;
}