QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#288347#7883. Takeout Deliveringckiseki#ML 0ms0kbC++203.2kb2023-12-22 15:38:202023-12-22 15:38:20

Judging History

你现在查看的是最新测评结果

  • [2023-12-22 15:38:20]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:0kb
  • [2023-12-22 15:38:20]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

constexpr int N = 300000 + 5;
constexpr int K = 20;

#define all(x) begin(x), end(x)
#ifdef CKISEKI
#include <experimental/iterator>
#define debug(a...) debug_(#a, a)
#define orange(a...) orange_(#a, a)
void debug_(auto s, auto ...a) {
  cerr << "\e[1;32m(" << s << ") = (";
  int f = 0;
  (..., (cerr << (f++ ? ", " : "") << a));
  cerr << ")\e[0m\n";
}
void orange_(auto s, auto L, auto R) {
  cerr << "\e[1;33m[ " << s << " ] = [ ";
  using namespace experimental;
  copy(L, R, make_ostream_joiner(cerr, ", "));
  cerr << " ]\e[0m\n";
}
#else
#define safe ((void)0)
#define debug(...) safe
#define orange(...) safe
#endif

struct Dsu {
  vector<int> pa, rk;
  Dsu(int n) : pa(n), rk(n) {
    iota(all(pa), 0);
  }
  int anc(int x) {
    return x==pa[x] ? x : pa[x]=anc(pa[x]);
  }
  bool join(int x, int y) {
    x = anc(x);
    y = anc(y);
    if (x == y) return false;
    if (rk[x] < rk[y]) swap(x, y);
    if (rk[x] == rk[y]) ++rk[x];
    pa[y] = x;
    return true;
  }
};

vector<pair<int, int>> g[N];

struct D {
  vector<int> v;
  D() : v{} {}
  explicit D(const vector<int> &oth) : v{oth} {}
  auto begin() { return v.begin(); }
  auto end() { return v.end(); }
  D operator+(const D &rhs) const {
    auto ret = v;
    for (auto x : rhs.v)
      ret.push_back(x);
    ranges::sort(ret, greater<>());
    ret.resize(min(2, int(ret.size())));
    return D{ret};
  }
};

D val[N][K];
int pa[N][K];
int tin[N], tout[N], tc;

void dfs(int u, int f) {
  tin[u] = tc++;
  for (int i = 1; i < K; ++i) {
    val[u][i] = val[u][i - 1] + val[pa[u][i - 1]][i - 1];
    pa[u][i] = pa[pa[u][i - 1]][i - 1];
  }
  for (auto [v, w] : g[u]) {
    if (v != f) {
      val[v][0] = D(vector<int>(1, w));
      pa[v][0] = u;
      dfs(v, u);
    }
  }
  tout[u] = tc;
}

bool anc(int u, int v) {
  return tin[u] <= tin[v] and tout[v] <= tout[u];
}

int lca(int u, int v) {
  if (anc(u, v))
    return u;
  for (int i = K - 1; i >= 0; --i)
    if (!anc(pa[u][i], v))
      u = pa[u][i];
  return pa[u][0];
}

D up(int u, int f) {
  assert(anc(f, u));
  if (u == f)
    return {};
  D ret = {};
  for (int i = K - 1; i >= 0; --i) {
    if (!anc(pa[u][i], f)) {
      ret = ret + val[u][i];
      u = pa[u][i];
    }
  }
  return ret + val[u][0];
}

D query(int u, int v) {
  int o = lca(u, v);
  return up(u, o) + up(v, o);
}

int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  int n, m;
  cin >> n >> m;

  int ans = 2e9;
  vector<tuple<int,int,int>> e;
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    --u, --v;
    e.emplace_back(w, u, v);
    tie(u, v) = minmax(u, v);
    if (u == 0 && v == n - 1)
      ans = min(ans, w);
  }
  ranges::sort(e);

  Dsu dsu(n);
  for (auto [w, u, v] : e) {
    if (dsu.join(u, v)) {
      g[u].emplace_back(v, w);
      g[v].emplace_back(u, w);
    }
  }

  dfs(0, 0);

  for (auto [w, u, v] : e) {
    for (int s : {0, n - 1}) {
      const int t = n - 1 - s;

      vector<int> ws = {w};
      for (auto wi : query(u, s))
        ws.push_back(wi);
      for (auto wi : query(v, t))
        ws.push_back(wi);
      ranges::sort(ws, greater<>());
      if (ws.size() == 1) {
        ans = min(ans, ws[0]);
      } else {
        ans = min(ans, ws[0] + ws[1]);
      }
    }
  }

  cout << ans << "\n";
  return 0;
}

详细

Test #1:

score: 0
Memory Limit Exceeded

input:

4 6
1 2 2
1 3 4
1 4 7
2 3 1
2 4 3
3 4 9

output:

5

result: