제출 #1161576

#제출 시각아이디문제언어결과실행 시간메모리
1161576Zero_OPWild Boar (JOI18_wild_boar)C++20
12 / 100
58 ms103752 KiB
#include <bits/stdc++.h>

using namespace std;

#define FOR(i, l, r) for(int i = (l); i < (r); ++i)
#define ROF(i, r, l) for(int i = (r) - 1; i >= (l); --i)

#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second

#define all(v) begin(v), end(v)
#define rall(v) rbegin(v), rend(v)
#define pb push_back
#define eb emplace_back
#define sz(v) (int)v.size()
#define sum_of(v) accumulate(all(v), 0ll)

#define dbg(x) "[" #x " = " << (x) << "]"

template<typename T>
      bool minimize(T& a, const T& b){
            if(a > b) return a = b, true;
            return false;
      }

template<typename T>
      bool maximize(T& a, const T& b){
            if(a < b) return a = b, true;
            return false;
      }

using ll = long long;
using db = double;
using ld = long double;
using ull = unsigned long long;

using pi = pair<int, int>;
using pl = pair<ll, ll>;
using pd = pair<db, db>;

using vi = vector<int>;
using vb = vector<bool>;
using vc = vector<char>;
using vl = vector<ll>;
using vd = vector<db>;

using vpi = vector<pi>;
using vpl = vector<pl>;

void setIO(){
      ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef LOCAL
      freopen("task.inp", "r", stdin);
      freopen("task.out", "w", stdout);
#endif // LOCAL
}

const int MAX = 1e5 + 5;
const ll inf = 1e18;
using dijkstra_node = tuple<ll, int, int>;

struct path{
      int s, t; ll dist;
      path(int s, int t, ll dist) : s(s), t(t), dist(dist) {}

      bool operator < (const path& o) const {
            return dist < o.dist;
      }
};

const int KEEP = 5;
struct info{
      vector<path> paths;

      info() : paths() {}

      void clear(){
            paths.clear();
      }

      void insert(const path& p){
            paths.pb(p);
      }

      void filter(){
            sort(all(paths));

            vector<path> result;
            FOR(i, 0, sz(paths)){
                  if(sz(result) >= KEEP) break;

                  bool need = true, equal_s = false, equal_t = false;
                  FOR(j, 0, sz(result)){
                        if(result[j].s == paths[i].s && result[j].t == paths[i].t){
                              need = false;
                              break;
                        }

                        if(result[j].s == paths[i].s) {
                              if(equal_s){
                                    need = false;
                                    break;
                              }

                              equal_s = true;
                        }

                        if(result[j].t == paths[i].t){
                              if(equal_t){
                                    need = false;
                                    break;
                              }

                              equal_t = true;
                        }
                  }

                  if(need) result.pb(paths[i]);
            }

            swap(paths, result);
      }

      ll get(){
            if(paths.empty()) return -1;
            return paths[0].dist;
      }
} options[2000][2000], st[MAX << 2];
int X[MAX];

void pull(info& result, const info& a, const info& b){
      result.clear();
      FOR(i, 0, sz(a.paths)){
            FOR(j, 0, sz(b.paths)){
                  if(a.paths[i].t != b.paths[j].s){
                        result.insert(path(a.paths[i].s, b.paths[j].t, a.paths[i].dist + b.paths[j].dist));
                  }
            }
      }

      result.filter();
}

void refine(int id, int l, int r, int u, int v){
      if(l == r){
            st[id] = options[X[l]][X[l+1]];
      } else{
            int mid = l + r >> 1;
            if(u <= mid) refine(id << 1, l, mid, u, v);
            if(mid < v)  refine(id << 1 | 1, mid + 1, r, u, v);
            pull(st[id], st[id << 1], st[id << 1 | 1]);
      }
}

int main(){
      setIO();

      int N, M, T, L;
      cin >> N >> M >> T >> L;

      int cnt = 0;
      vector<vi> idx(N, vi(N, -1));
      vector<vpi> adj(N);
      vpi e(M * 2);
      FOR(i, 0, M){
            int u, v, w;
            cin >> u >> v >> w;
            --u, --v;
            adj[u].eb(v, w);
            adj[v].eb(u, w);
            e[idx[u][v] = cnt++] = mp(u, v);
            e[idx[v][u] = cnt++] = mp(v, u);
      }

      FOR(i, 0, L) cin >> X[i], --X[i];

      priority_queue<dijkstra_node, vector<dijkstra_node>, greater<dijkstra_node>> pq;

      FOR(s, 0, N){
            for(auto [_, __] : adj[s]){
                  vl dists(cnt, inf);

                  dists[idx[s][_]] = __;
                  pq.push(mt(__, _, s));

                  while(!pq.empty()){
                        ll dist; int u, pre; tie(dist, u, pre) = pq.top(); pq.pop();
                        if(dists[idx[u][pre]] < dist) continue;

                        for(auto [v, w] : adj[u]) if(v != pre){
                              int pos = idx[u][v];
                              if(dists[pos] > dist + w){
                                    dists[pos] = dist + w;
                                    pq.push(mt(dists[pos], v, u));
                              }
                        }
                  }

                  FOR(i, 0, 2 * M) if(dists[i] != inf){
                        int pre, cur;
                        tie(pre, cur) = e[i];
                        options[s][cur].insert(path(_, pre, dists[i]));
                  }
            }
      }

      refine(1, 0, L-2, 0, L-2);

      while(T--){
            int P, Q;
            cin >> P >> Q;
            --P, --Q;
            X[P] = Q;
            refine(1, 0, L-2, P-1, P);
            cout << st[1].get() << '\n';
      }

      return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...