제출 #680449

#제출 시각아이디문제언어결과실행 시간메모리
680449rainboyWild Boar (JOI18_wild_boar)C11
0 / 100
1 ms596 KiB
#include <stdio.h> #include <stdlib.h> #include <string.h> #define N 2000 #define M 2000 #define M2 (M * 2) #define MM (M * M) #define K 6 #define L 100000 #define N_ (1 << 17) /* N_ = pow2(ceil(log2(L))) */ #define INF 0x3f3f3f3f3f3f3f3fLL long long min(long long a, long long b) { return a < b ? a : b; } unsigned int Z = 12345; int rand_() { return (Z *= 3) >> 1; } int ij[M2], cc[M], m; int *eh[N], eo[N], n; void append(int i, int h) { int o = eo[i]++; if (o >= 2 && (o & o - 1) == 0) eh[i] = (int *) realloc(eh[i], o * 2 * sizeof *eh[i]); eh[i][o] = h; } long long *dd_; int iq[M2 + 1], pq[M2], cnt; int lt(int i, int j) { return dd_[i] < dd_[j]; } int p2(int p) { return (p *= 2) > cnt ? 0 : (p < cnt && lt(iq[p + 1], iq[p]) ? p + 1 : p); } void pq_up(int i) { int p, q, j; for (p = pq[i]; (q = p / 2) && lt(i, j = iq[q]); p = q) iq[pq[j] = p] = j; iq[pq[i] = p] = i; } void pq_dn(int i) { int p, q, j; for (p = pq[i]; (q = p2(p)) && lt(j = iq[q], i); p = q) iq[pq[j] = p] = j; iq[pq[i] = p] = i; } void pq_add_last(int i) { iq[pq[i] = ++cnt] = i; } int pq_remove_first() { int i = iq[1], j = iq[cnt--]; if (j != i) pq[j] = 1, pq_dn(j); pq[i] = 0; return i; } void solve(long long *dd, int u) { static int kk[N]; int h, i, o; memset(dd, 0x3f, m * 2 * sizeof *dd), memset(kk, 0, n * sizeof *kk); dd_ = dd, dd[u] = cc[u >> 1], pq_add_last(u); while (cnt) { h = pq_remove_first(), i = ij[h ^ 1]; if (kk[i] < 2) { kk[i]++; for (o = eo[i]; o--; ) { int h_ = eh[i][o]; long long d = dd[h] + cc[h_ >> 1]; if ((h ^ h_) != 1 && dd[h_] > d) { if (dd[h_] == INF) pq_add_last(h_); dd[h_] = d, pq_up(h_); } } } } } int uu1[MM], vv1[MM]; long long ww1[MM]; int compare_uv(int h1, int h2) { return uu1[h1] != uu1[h2] ? uu1[h1] - uu1[h2] : vv1[h1] - vv1[h2]; } int compare_w(int h1, int h2) { return ww1[h1] == ww1[h2] ? 0 : (ww1[h1] < ww1[h2] ? -1 : 1); } int (*compare)(int, int); void sort(int *gg, int l, int r) { while (l < r) { int i = l, j = l, k = r, g = gg[l + rand_() % (r - l)], tmp; while (j < k) { int c = compare(gg[j], g); if (c == 0) j++; else if (c < 0) { tmp = gg[i], gg[i] = gg[j], gg[j] = tmp; i++, j++; } else { k--; tmp = gg[j], gg[j] = gg[k], gg[k] = tmp; } } sort(gg, l, i); l = k; } } int simplify(int k) { static int dd1[M2], dd2[M2], gg[MM], uu_[MM], vv_[MM]; static long long ww_[MM]; int k_, g, g_, u, v; long long w; for (g = 0; g < k; g++) gg[g] = g; compare = compare_uv, sort(gg, 0, k); k_ = 0; for (g = 0; g < k; g++) { u = uu1[gg[g]], v = vv1[gg[g]]; g_ = g, w = INF; while (g_ < k && uu1[gg[g_]] == u && vv1[gg[g_]] == v) w = min(w, ww1[gg[g_++]]); uu_[k_] = u, vv_[k_] = v, ww_[k_] = w, k_++; } memcpy(uu1, uu_, k_ * sizeof *uu_); memcpy(vv1, vv_, k_ * sizeof *vv_); memcpy(ww1, ww_, k_ * sizeof *ww_); k = k_; for (g = 0; g < k; g++) gg[g] = g; compare = compare_w, sort(gg, 0, k); k_ = 0; for (g = 0; g < k; g++) { g_ = gg[g], u = uu1[g_], v = vv1[g_], w = ww1[g_]; if (dd1[u] >= 2 || dd2[v] >= 2) continue; dd1[u]++, dd2[v]++; if (k_ < K) uu_[k_] = u, vv_[k_] = v, ww_[k_] = w, k_++; } for (g = 0; g < k; g++) { u = uu1[g], v = vv1[g]; dd1[u] = 0, dd2[v] = 0; } memcpy(uu1, uu_, k_ * sizeof *uu_); memcpy(vv1, vv_, k_ * sizeof *vv_); memcpy(ww1, ww_, k_ * sizeof *ww_); return k_; } int uu[N][N][K], vv[N][N][K], kk[N][N]; long long ww[N][N][K]; int uu_[N_ * 2][K], vv_[N_ * 2][K], kk_[N_ * 2], n_; long long ww_[N_ * 2][K]; void pul(int i) { int l, r, k, g1, g2; l = i << 1, r = l | 1; if (kk_[l] == -1 && kk_[r] == -1) kk_[i] = -1; else if (kk_[r] == -1) { memcpy(uu_[i], uu_[l], kk_[l] * sizeof *uu_[l]); memcpy(vv_[i], vv_[l], kk_[l] * sizeof *vv_[l]); memcpy(ww_[i], ww_[l], kk_[l] * sizeof *ww_[l]); kk_[i] = kk_[l]; } else if (kk_[l] == -1) { memcpy(uu_[i], uu_[r], kk_[r] * sizeof *uu_[r]); memcpy(vv_[i], vv_[r], kk_[r] * sizeof *vv_[r]); memcpy(ww_[i], ww_[r], kk_[r] * sizeof *ww_[r]); kk_[i] = kk_[r]; } else { k = 0; for (g1 = 0; g1 < kk_[l]; g1++) for (g2 = 0; g2 < kk_[r]; g2++) if ((vv_[l][g1] ^ uu_[r][g2]) != 1) uu1[k] = uu_[l][g1], vv1[k] = vv_[r][g2], ww1[k] = min(ww_[l][g1] + ww_[r][g2], INF), k++; k = simplify(k); memcpy(uu_[i], uu1, k * sizeof *uu1); memcpy(vv_[i], vv1, k * sizeof *vv1); memcpy(ww_[i], ww1, k * sizeof *ww1); kk_[i] = k; } } int ii[L], l; void build() { int h, i, j; n_ = 1; while (n_ < l) n_ <<= 1; for (h = 0; h < n_; h++) if (h + 1 < l) { i = ii[h], j = ii[h + 1]; memcpy(uu_[n_ + h], uu[i][j], kk[i][j] * sizeof *uu[i][j]); memcpy(vv_[n_ + h], vv[i][j], kk[i][j] * sizeof *vv[i][j]); memcpy(ww_[n_ + h], ww[i][j], kk[i][j] * sizeof *ww[i][j]); kk_[n_ + h] = kk[i][j]; } else kk_[n_ + h] = -1; for (h = n_ - 1; h > 0; h--) pul(h); } void upd(int h) { int i = ii[h], j = ii[h + 1]; memcpy(uu_[n_ + h], uu[i][j], kk[i][j] * sizeof *uu[i][j]); memcpy(vv_[n_ + h], vv[i][j], kk[i][j] * sizeof *vv[i][j]); memcpy(ww_[n_ + h], ww[i][j], kk[i][j] * sizeof *ww[i][j]); kk_[n_ + h] = kk[i][j]; h += n_; while (h > 1) pul(h >>= 1); } int main() { static long long dd[M2][M2]; int q, k, g, h, i, j, u, v, o, o_; scanf("%d%d%d%d", &n, &m, &q, &l); for (i = 0; i < n; i++) eh[i] = (int *) malloc(2 * sizeof *eh[i]); for (h = 0; h < m; h++) { scanf("%d%d%d", &i, &j, &cc[h]), i--, j--; ij[h << 1 | 0] = i, ij[h << 1 | 1] = j; append(i, h << 1 | 0), append(j, h << 1 | 1); } for (u = 0; u < m * 2; u++) solve(dd[u], u); for (i = 0; i < n; i++) for (j = 0; j < n; j++) { k = 0; for (o = eo[i]; o--; ) { u = eh[i][o]; for (o_ = eo[j]; o_--; ) { v = eh[j][o_] ^ 1; uu1[k] = u, vv1[k] = v, ww1[k] = dd[u][v], k++; } } k = simplify(k); memcpy(uu[i][j], uu1, k * sizeof *uu1); memcpy(vv[i][j], vv1, k * sizeof *vv1); memcpy(ww[i][j], ww1, k * sizeof *ww1); kk[i][j] = k; } for (h = 0; h < l; h++) scanf("%d", &ii[h]), ii[h]--; build(); while (q--) { long long ans; scanf("%d%d", &h, &i), h--, i--; ii[h] = i; if (h > 0) upd(h - 1); if (h + 1 < l) upd(h); ans = INF; for (g = 0; g < kk_[1]; g++) ans = min(ans, ww_[1][g]); printf("%lld\n", ans == INF ? -1 : ans); } return 0; }

컴파일 시 표준 에러 (stderr) 메시지

wild_boar.c: In function 'append':
wild_boar.c:28:23: warning: suggest parentheses around '-' in operand of '&' [-Wparentheses]
   28 |  if (o >= 2 && (o & o - 1) == 0)
      |                     ~~^~~
wild_boar.c: In function 'main':
wild_boar.c:242:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  242 |  scanf("%d%d%d%d", &n, &m, &q, &l);
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wild_boar.c:246:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  246 |   scanf("%d%d%d", &i, &j, &cc[h]), i--, j--;
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wild_boar.c:269:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  269 |   scanf("%d", &ii[h]), ii[h]--;
      |   ^~~~~~~~~~~~~~~~~~~
wild_boar.c:274:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  274 |   scanf("%d%d", &h, &i), h--, i--;
      |   ^~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...