結果

問題 No.1212 Second Path
ユーザー 👑 hos.lyrichos.lyric
提出日時 2020-08-30 17:17:39
言語 D
(dmd 2.107.1)
結果
AC  
実行時間 624 ms / 3,000 ms
コード長 7,024 bytes
コンパイル時間 2,230 ms
コンパイル使用メモリ 109,404 KB
実行使用メモリ 82,500 KB
最終ジャッジ日時 2023-09-04 09:42:08
合計ジャッジ時間 21,875 ms
ジャッジサーバーID
(参考情報)
judge12 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 366 ms
82,364 KB
testcase_01 AC 611 ms
81,284 KB
testcase_02 AC 620 ms
79,752 KB
testcase_03 AC 623 ms
81,036 KB
testcase_04 AC 620 ms
76,988 KB
testcase_05 AC 624 ms
76,692 KB
testcase_06 AC 318 ms
72,676 KB
testcase_07 AC 410 ms
71,856 KB
testcase_08 AC 408 ms
72,212 KB
testcase_09 AC 411 ms
71,276 KB
testcase_10 AC 418 ms
71,584 KB
testcase_11 AC 420 ms
71,560 KB
testcase_12 AC 416 ms
71,156 KB
testcase_13 AC 410 ms
71,308 KB
testcase_14 AC 415 ms
71,728 KB
testcase_15 AC 425 ms
71,140 KB
testcase_16 AC 413 ms
71,660 KB
testcase_17 AC 363 ms
82,500 KB
testcase_18 AC 109 ms
4,400 KB
testcase_19 AC 109 ms
4,400 KB
testcase_20 AC 113 ms
13,204 KB
testcase_21 AC 106 ms
4,376 KB
testcase_22 AC 108 ms
4,404 KB
testcase_23 AC 88 ms
4,380 KB
testcase_24 AC 94 ms
4,404 KB
testcase_25 AC 93 ms
4,500 KB
testcase_26 AC 94 ms
4,376 KB
testcase_27 AC 93 ms
5,880 KB
testcase_28 AC 93 ms
4,380 KB
testcase_29 AC 499 ms
82,316 KB
testcase_30 AC 513 ms
82,076 KB
testcase_31 AC 508 ms
82,268 KB
testcase_32 AC 347 ms
57,308 KB
testcase_33 AC 297 ms
44,764 KB
testcase_34 AC 399 ms
68,616 KB
testcase_35 AC 152 ms
11,120 KB
testcase_36 AC 352 ms
57,456 KB
testcase_37 AC 350 ms
52,452 KB
testcase_38 AC 340 ms
57,072 KB
testcase_39 AC 255 ms
35,268 KB
testcase_40 AC 124 ms
4,940 KB
testcase_41 AC 341 ms
55,176 KB
testcase_42 AC 2 ms
4,380 KB
testcase_43 AC 2 ms
4,376 KB
testcase_44 AC 2 ms
4,376 KB
testcase_45 AC 312 ms
72,556 KB
testcase_46 AC 295 ms
71,912 KB
testcase_47 AC 291 ms
72,208 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.mathspecial, std.numeric, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }


int N;
int[] A, B;
long[] C;

int[][] G;
int[] par, dep;
long[] dist;

void dfs(int u, int p, int ip) {
  par[u] = p;
  dep[u] = (p == -1) ? 0 : (dep[p] + 1);
  dist[u] = (p == -1) ? 0 : (dist[p] + C[ip]);
  foreach (i; G[u]) {
    const v = A[i] ^ B[i] ^ u;
    if (v != p) {
      dfs(v, u, i);
    }
  }
}

enum E = 17;
enum INF = 10L^^18;

struct Info {
  int last;
  long mn;
  long[2] xs;
};
Info mul(in Info f, in Info g) {
  Info h;
  h.last = g.last;
  h.mn = min(f.mn,
             (g.xs[0] != dist[f.last] - dist[par[f.last]]) ? g.xs[0] : g.xs[1],
             g.mn);
  h.xs = f.xs;
  return h;
}

void main() {
  try {
    for (; ; ) {
      N = readInt();
      A = new int[N - 1];
      B = new int[N - 1];
      C = new long[N - 1];
      foreach (i; 0 .. N - 1) {
        A[i] = readInt() - 1;
        B[i] = readInt() - 1;
        C[i] = readLong();
      }
      const Q = readInt();
      auto X = new int[Q];
      auto Y = new int[Q];
      foreach (q; 0 .. Q) {
        X[q] = readInt() - 1;
        Y[q] = readInt() - 1;
      }
      
      G = new int[][N];
      foreach (i; 0 .. N - 1) {
        G[A[i]] ~= i;
        G[B[i]] ~= i;
      }
      par = new int[N];
      dep = new int[N];
      dist = new long[N];
      dfs(0, -1, -1);
      auto dd = new Info[][](E, N);
      foreach (u; 0 .. N) {
        dd[0][u].last = u;
        dd[0][u].mn = INF;
        dd[0][u].xs[] = INF;
        foreach (i; G[u]) {
          const v = A[i] ^ B[i] ^ u;
          if (v != par[u]) {
            long tmp = C[i];
            foreach (k; 0 .. 2) {
              if (dd[0][u].xs[k] > tmp) {
                swap(dd[0][u].xs[k], tmp);
              }
            }
          }
        }
      }
      foreach (e; 0 .. E - 1) {
        foreach (u; 0 .. N) {
          const l = dd[e][u].last;
          if (l == -1 || par[l] == -1) {
            dd[e + 1][u] = dd[e][u];
          } else {
            dd[e + 1][u] = mul(dd[e][u], dd[e][par[l]]);
          }
        }
      }
      debug {
        foreach (e; 0 .. E - 1) {
          writefln("dd[%s] = %s", e, dd[e]);
        }
      }
      
      auto mns = new long[][](N, 3);
      foreach (u; 0 .. N) {
        mns[u][] = INF;
        foreach (i; G[u]) {
          long tmp = C[i];
          foreach (k; 0 .. 3) {
            if (mns[u][k] > tmp) {
              swap(mns[u][k], tmp);
            }
          }
        }
      }
      
      debug {
        auto d = new long[][](N, N);
        foreach (u; 0 .. N) {
          d[u][] = INF;
          d[u][u] = 0;
        }
        foreach (i; 0 .. N - 1) {
          chmin(d[A[i]][B[i]], C[i]);
          chmin(d[B[i]][A[i]], C[i]);
        }
        foreach (w; 0 .. N) foreach (u; 0 .. N) foreach (v; 0 .. N) {
          chmin(d[u][v], d[u][w] + d[w][v]);
        }
      }
      
      foreach (q; 0 .. Q) {
        int u = X[q], v = Y[q];
        if (dep[u] > dep[v]) {
          swap(u, v);
        }
        debug {
          writefln("dep[%s] = %s, dep[%s] = %s", u, dep[u], v, dep[v]);
        }
        int lca;
        long ans = INF;
        Info fu, fv;
        fu.last = fv.last = -2;
        foreach_reverse (e; 0 .. E) {
          if (dep[u] <= dep[v] - (1 << e)) {
            debug {
              writefln("%s -> %s", v, par[dd[e][v].last]);
            }
            fv = (fv.last == -2) ? dd[e][v] : mul(fv, dd[e][v]);
            v = par[dd[e][v].last];
          }
        }
        if (u == v) {
          debug {
            writeln("u == v");
            writeln("fv = ", fv);
          }
          lca = u;
          chmin(ans, (mns[u][0] != dist[fv.last] - dist[u]) ? mns[u][0] : mns[u][1]);
          chmin(ans, fv.mn);
          chmin(ans, fv.xs[0]);
        } else {
          foreach_reverse (e; 0 .. E) {
            if (dep[u] - (1 << e) >= 0 && par[dd[e][u].last] != par[dd[e][v].last]) {
              debug {
                writefln("%s -> %s, %s -> %s", u, par[dd[e][u].last], v, par[dd[e][v].last]);
              }
              fu = (fu.last == -2) ? dd[e][u] : mul(fu, dd[e][u]);
              fv = (fv.last == -2) ? dd[e][v] : mul(fv, dd[e][v]);
              u = par[dd[e][u].last];
              v = par[dd[e][v].last];
            }
          }
          debug {
            writeln("lca = ", lca);
            writeln("fu = ", fu);
            writeln("fv = ", fv);
          }
          lca = par[u];
          fu = (fu.last == -2) ? dd[0][u] : mul(fu, dd[0][u]);
          fv = (fv.last == -2) ? dd[0][v] : mul(fv, dd[0][v]);
          long[2] tmps = [dist[u] - dist[lca], dist[v] - dist[lca]];
          if (tmps[0] > tmps[1]) {
            swap(tmps[0], tmps[1]);
          }
          chmin(ans, (mns[lca][0] != tmps[0]) ? mns[lca][0] : (mns[lca][1] != tmps[1]) ? mns[lca][1] : mns[lca][2]);
          chmin(ans, fu.mn);
          chmin(ans, fu.xs[0]);
          chmin(ans, fv.mn);
          chmin(ans, fv.xs[0]);
        }
        debug {
          writeln("lca = ", lca, ", ans = ", ans);
        }
        
        debug {
          long brt = INF;
          foreach (i; 0 .. N - 1) {
            if (d[X[q]][Y[q]] == d[X[q]][A[i]] + C[i] + d[B[i]][Y[q]] ||
                d[X[q]][Y[q]] == d[X[q]][B[i]] + C[i] + d[A[i]][Y[q]]) {
              // edge on the path
            } else if (d[X[q]][Y[q]] == d[X[q]][A[i]] + d[A[i]][Y[q]] ||
                       d[X[q]][Y[q]] == d[X[q]][B[i]] + d[B[i]][Y[q]]) {
              chmin(brt, C[i]);
            }
          }
          assert(brt == ans, format("query %s %s: %s %s", X[q], Y[q], brt, ans));
          assert(d[X[q]][Y[q]] == dist[X[q]] + dist[Y[q]] - 2 * dist[lca]);
        }
        
        if (ans >= INF) {
          writeln(-1);
        } else {
          ans *= 2;
          ans += dist[X[q]] + dist[Y[q]] - 2 * dist[lca];
          writeln(ans);
        }
      }
    }
  } catch (EOFException e) {
  }
}
0