Submission #416908

#TimeUsernameProblemLanguageResultExecution timeMemory
416908Mamnoon_SiamWild Boar (JOI18_wild_boar)C++17
100 / 100
10593 ms712724 KiB
#include <bits/stdc++.h> using namespace std; using ii = pair<int, int>; using ll = long long; using vi = vector<int>; #define fi first #define se second #define all(v) begin(v), end(v) #define sz(v) (int)(v.size()) using pli = pair<ll, int>; template<typename T> inline void chkmin(T& x, T y) { x = x < y ? x : y; } const ll inf = 1e18; tuple<ll,int,int> shortest_path(vector<pair<ii,ll>>& ls, int anot, int bnot) { // best path *---a--->--...-->---b---* in ls s.t. a != anot, b != bnot tuple<ll,int,int> opt{inf, -1, -1}; for(auto [pa, w] : ls) { auto [s, t] = pa; if(s != anot and t != bnot) { opt = min(opt, make_tuple(w, s, t)); } } return opt; } struct path { int s, t; ll w; }; vector<path> get_top5(vector<pair<ii,ll>>& ls) { vector<path> ret; auto [w1, a1, b1] = shortest_path(ls, -1, -1); auto [w2, a2, b2] = shortest_path(ls, a1, -1); auto [w3, a3, b3] = shortest_path(ls, a1, b2); auto [w4, a4, b4] = shortest_path(ls, -1, b1); auto [w5, a5, b5] = shortest_path(ls, a4, b1); if(~a1) ret.push_back({a1, b1, w1}); if(~a2) ret.push_back({a2, b2, w2}); if(~a3) ret.push_back({a3, b3, w3}); if(~a4) ret.push_back({a4, b4, w4}); if(~a5) ret.push_back({a5, b5, w5}); return ret; } vector<path> merge(vector<path> L, vector<path> R) { map<ii, ll> opt; for(path& l : L) { for(path& r : R) { if(l.t != r.s) { if(!opt.count(ii(l.s, r.t))) { opt[ii(l.s, r.t)] = l.w + r.w; } else { chkmin(opt[ii(l.s, r.t)], l.w + r.w); } } } } std::vector<path> ret; vector<pair<ii,ll>> ls(all(opt)); return get_top5(ls); } int n, m, T, L; int A[4004], B[4004], C[4004]; vi ine[2002], oute[2002]; ll cost[4004][4004]; // cost[i][j] = shortest path from i-th directed edge to j-th directed edge int X[100005]; vector<path> top5[2002][2002]; vector<path> tree[100005 << 2]; void build(int u = 1, int b = 1, int e = L-1) { if(b == e) { tree[u] = top5[X[b]][X[b+1]]; return; } int mid = (b + e) >> 1; build(u << 1, b, mid); build(u << 1 | 1, mid+1, e); tree[u] = merge(tree[u << 1], tree[u << 1 | 1]); } void update(int pos, int u = 1, int b = 1, int e = L-1) { if(b == e) { tree[u] = top5[X[b]][X[b+1]]; return; } int mid = (b + e) >> 1; if(pos <= mid) update(pos, u << 1, b, mid); else update(pos, u << 1 | 1, mid+1, e); tree[u] = merge(tree[u << 1], tree[u << 1 | 1]); } #ifdef LOCAL #include "../debug.h" #else #define debug(...) #endif int main(int argc, char const *argv[]) { #ifdef LOCAL freopen("in", "r", stdin); #endif scanf("%d %d %d %d", &n, &m, &T, &L); for(int i = 1; i <= m; ++i) { scanf("%d %d %d", &A[2*i], &B[2*i], &C[2*i]); A[2*i+1] = B[2*i]; B[2*i+1] = A[2*i]; C[2*i+1] = C[2*i]; ine[B[2*i]].emplace_back(2*i); oute[A[2*i]].emplace_back(2*i); ine[B[2*i+1]].emplace_back(2*i+1); oute[A[2*i+1]].emplace_back(2*i+1); } for(int i = 1; i <= n; ++i) { debug(ine[i], oute[i]); } for(int i = 1; i <= L; ++i) { scanf("%d", &X[i]); } for(int src = 2; src <= 2*m+1; ++src) { // for(int src : {4}) { vector<bool> done(2*m+2); ll *dis = cost[src]; fill(dis+2, dis+2*m+2, inf); debug(vector<ll>(dis+2, dis+2*m+2)); dis[src] = C[src]; debug(dis[src]); priority_queue<pli, vector<pli>, greater<pli>> Q; Q.emplace(dis[src], src); while(sz(Q)) { int u = Q.top().se; debug(u); Q.pop(); if(done[u]) continue; done[u] = 1; for(int v : oute[B[u]]) if((u^v)>>1) { debug(v); ll nw = dis[u] + C[v]; debug(nw); debug(dis[7]); if(nw < dis[v]) { dis[v] = nw; Q.emplace(dis[v], v); } } } debug(dis[7]); } for(int a = 1; a <= n; ++a) { for(int b = 1; b <= n; ++b) if(a != b) { vector<pair<ii,ll>> ls; for(int s : oute[a]) for(int t : ine[b]) if(cost[s][t] < inf) ls.push_back({{s>>1, t>>1}, cost[s][t]}); top5[a][b] = get_top5(ls); } } build(); while(T--) { int p, q; scanf("%d %d", &p, &q); X[p] = q; update(p-1); update(p); ll ans = inf; for(path& pa : tree[1]) chkmin(ans, pa.w); printf("%lld\n", ans == inf ? -1 : ans); } return 0; }

Compilation message (stderr)

wild_boar.cpp: In function 'int main(int, const char**)':
wild_boar.cpp:111:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  111 |   scanf("%d %d %d %d", &n, &m, &T, &L);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wild_boar.cpp:113:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  113 |     scanf("%d %d %d", &A[2*i], &B[2*i], &C[2*i]);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wild_boar.cpp:126:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  126 |     scanf("%d", &X[i]);
      |     ~~~~~^~~~~~~~~~~~~
wild_boar.cpp:170:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  170 |     scanf("%d %d", &p, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...