AOJ1505 Dungeon

Dungeon | Aizu Online Judge

Introduction to Programming Introduction to Algorithms and Data Structures Library of Data Structures Library of Graph Algorithms Library of Computational Geometry Library of Dynamic Programming Library of Number Theory

まず最初dijkstraの始点を としてスタート地点からの最短経路と,ゴール地点からの最短経路を出しておく.これで各クエリに対してで答えられるようになったが, なので間に合わない.
(スタート地点からの最短コスト, 頂点番号)のpairで,(ゴール地点からの最短コスト, 頂点番号)のpairでsortする.また頂点番号がsort後の配列のどこのindexかを持っておく.

スタート地点からのコスト

index 0 1 2 3
cost 0 2 3 3
頂点 0 2 1 3

ゴール地点からのコスト

index 0 1 2 3
cost 0 1 3 4
頂点 3 2 0 1

スタート地点に関して頂点番号 のsort後の配列のindexの変換テーブル

頂点 0 1 2 3
index 0 2 1 3

次にクエリ でsortする. 少なくともかかる,という制限なのでを優先してsortすれば,それ以前のものは候補に上がらないので,省いて良い.この省くというのを表現するのにBITを用いた.より小さい所は変換テーブルを用いてそのindexに する.次に 以下を満たす最大のindex持ってきてBITを用いてその区間和を引く.

説明が全く出来ている気がしない.後で見直し

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <queue>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1LL<<61
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct edge {
  int from,to;
  ll cost;

  edge(int t,ll c) : to(t),cost(c) {}
  edge(int f,int t,ll c) : from(f),to(t),cost(c) {}

  bool operator<(const edge &e) const {
      return cost < e.cost;
  }
};

vector<edge> G[100005];
ll d[100005], d2[100005];

void dijkstra(int s, int n) {
  priority_queue<pair<ll, ll> , vector<pair<ll, ll> >, greater<pair<ll, ll> > > que;
  fill(d, d+n, INF);

  d[s] = 0;
  que.push(P(0,s));

  while(que.size()) {
      P p = que.top();
      que.pop();

      int v = p.second;
      if(d[v] < p.first) continue;

      rep(i, G[v].size()) {
          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));
          }
      }
  }
}

struct BIT {
  vector<int> bit;

  BIT(int n) : bit(n+1) {}

  int sum(int i) {
      int s = 0;
      while(i > 0) {
          s += bit[i];
          i -= i & -i;
      }
      return s;
  }

  void add(int i,int x) {
      while(i <= bit.size()) {
          bit[i] += x;
          i += i & -i;
      }
  }
};

int main() {
  int n, m;
  cin >> n >> m;

  rep(i, m) {
      ll a, b, c;
      cin >> a >> b >> c;

      G[a].push_back(edge(b, c));
      G[b].push_back(edge(a, c));
  }

  dijkstra(n-1, n);
  memset(d2, 0, sizeof(d2));
  rep(i, n) {
      d2[i] = d[i];
  }

  dijkstra(0, n);

  vector<ll> d3(n);
  vector<pair<ll, int> > D, D2;
  rep(i, n) {
      d3[i] = d[i];
      D.push_back(mp(d[i], i));
      D2.push_back(mp(d2[i], i));
  }

  sort(d3.begin(), d3.end());
  sort(D.begin(), D.end());
  sort(D2.begin(), D2.end());

  map<int, int> ma;
  rep(i, n) {
      ma[ D[i].second ] = i;
  }

  int q;
  cin >> q;

  vector<pair<pair<ll, ll> , int> > query(q);

  rep(i, q) {
      ll s, g;
      cin >> s >> g;

      query[i] = mp(mp(g, s), i);
  }

  sort(query.begin(), query.end());

  BIT bit(n + 5);
  vector<P> ans;
  int start = 0;
  rep(i, q) {
      ll s = query[i].first.second;
      ll g = query[i].first.first;
      int id = query[i].second;

      for(; start < n; start++) {
          if(g > D2[start].first) {
              int k = ma[ D2[start].second ];
              bit.add(k + 1, 1);
              continue;
          } else break;
      }

      vector<ll>::iterator ite = upper_bound(d3.begin(), d3.end(), s);
      int k = ite - d3.begin() - 1;
      if(k < 0) {
          ans.push_back(mp( id, 0));
      } else {
          int res = k + 1;
          res -= bit.sum(k + 1);
          ans.push_back(mp( id, res));
      }
  }

  sort(ans.begin(), ans.end());

  rep(i, ans.size()) {
      cout << ans[i].second << endl;
  }

  return 0;
}