QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#527907#3047. Wind of ChangeliuziaoTL 0ms0kbC++235.0kb2024-08-22 22:26:232024-08-22 22:26:25

Judging History

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

  • [2024-08-22 22:26:25]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-08-22 22:26:23]
  • 提交

answer

#include <bits/stdc++.h>

#define int int64_t

const int kMaxN = 2.5e5 + 5;

int n, rt1, rt2;
int a[kMaxN], b[kMaxN], sz1[kMaxN], mx1[kMaxN], sz2[kMaxN], mx2[kMaxN], ans[kMaxN];
int lg[kMaxN], sumw[kMaxN], dfn[kMaxN], st[kMaxN][19];
bool del1[kMaxN], del2[kMaxN], vis[kMaxN];
std::vector<int> idx1, idx2;
std::vector<std::pair<int, int>> G1[kMaxN], G2[kMaxN], T[kMaxN];

int get(int x, int y) { return dfn[x] < dfn[y] ? x : y; }

int LCA(int x, int y) {
  if (x == y) return x;
  if (dfn[x] > dfn[y]) std::swap(x, y);
  int k = lg[dfn[y] - dfn[x]];
  return get(st[dfn[x] + 1][k], st[dfn[y] - (1 << k) + 1][k]);
}

void _dfs(int u, int fa) {
  static int cnt = 0;
  st[dfn[u] = ++cnt][0] = fa;
  for (auto [v, w] : G2[u]) {
    if (v == fa) continue;
    sumw[v] = sumw[u] + w;
    _dfs(v, u);
  }
}

void prework() {
  _dfs(1, 0);
  lg[0] = -1;
  for (int i = 1; i <= n; ++i) lg[i] = lg[i >> 1] + 1;
  for (int i = 1; i <= lg[n]; ++i)
    for (int j = 1; j <= n - (1 << i) + 1; ++j)
      st[j][i] = get(st[j][i - 1], st[j + (1 << (i - 1))][i - 1]);
}

void getsz1(int u, int fa) {
  sz1[u] = 1, mx1[u] = 0;
  for (auto [v, w] : G1[u]) {
    if (v == fa || del1[v]) continue;
    getsz1(v, u);
    sz1[u] += sz1[v], mx1[u] = std::max(mx1[u], sz1[v]);
  }
}

void getrt1(int u, int fa, int tot) {
  mx1[u] = std::max(mx1[u], tot - sz1[u]);
  if (mx1[u] < mx1[rt1]) rt1 = u;
  for (auto [v, w] : G1[u]) {
    if (v == fa || del1[v]) continue;
    getrt1(v, u, tot);
  }
}

void _dfs1(int u, int fa) {
  idx1.emplace_back(u), vis[u] = 1;
  for (auto [v, w] : G1[u]) {
    if (v == fa || del1[v]) continue;
    a[v] = a[u] + w;
    _dfs1(v, u);
  }
}

void getsz2(int u, int fa) {
  sz2[u] = 1, mx2[u] = 0;
  for (auto [v, w] : T[u]) {
    if (v == fa || del2[v]) continue;
    getsz2(v, u);
    sz2[u] += sz2[v], mx2[u] = std::max(mx2[u], sz2[v]);
  }
}

void getrt2(int u, int fa, int tot) {
  mx2[u] = std::max(mx2[u], tot - sz2[u]);
  if (mx2[u] < mx2[rt2]) rt2 = u;
  for (auto [v, w] : T[u]) {
    if (v == fa || del2[v]) continue;
    getrt2(v, u, tot);
  }
}

void _dfs2(int u, int fa) {
  idx2.emplace_back(u);
  for (auto [v, w] : T[u]) {
    if (v == fa || del2[v]) continue;
    b[v] = b[u] + w;
    _dfs2(v, u);
  }
}

int getval(std::vector<int> &vec, int p) {
  if (p < 0 || p >= (int)vec.size()) return 1e18;
  else return vec[p];
}

void dfs2(int u) {
  b[u] = 0, _dfs2(u, 0);
  std::vector<int> pre(idx2.size()), suf(idx2.size());
  for (int i = 0; i < (int)idx2.size(); ++i) {
    pre[i] = std::min(getval(pre, i - 1), a[idx2[i]] + b[idx2[i]]);
  }
  for (int i = (int)idx2.size() - 1; ~i; --i) {
    suf[i] = std::min(getval(suf, i + 1), a[idx2[i]] + b[idx2[i]]);
  }
  for (int i = 0; i < (int)idx2.size(); ++i) {
    ans[idx2[i]] = std::min(ans[idx2[i]], a[idx2[i]] + b[idx2[i]] + std::min(getval(pre, i - 1), getval(suf, i + 1)));
  }
  idx2.clear(), idx2.shrink_to_fit();
  del2[u] = 1;
  for (auto [v, w] : T[u]) {
    if (del2[v]) continue;
    rt2 = 0, getsz2(v, 0), getrt2(v, 0, sz2[v]), dfs2(v);
  }
}

void build(std::vector<int> &vec) {
  std::sort(vec.begin(), vec.end(), [&] (int i, int j) { return dfn[i] < dfn[j]; });
  for (int i = 0, len = (int)vec.size(); i + 1 < len; ++i) {
    vec.emplace_back(LCA(vec[i], vec[i + 1]));
  }
  std::sort(vec.begin(), vec.end(), [&] (int i, int j) { return dfn[i] < dfn[j]; });
  vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
  for (int i = 0; i + 1 < (int)vec.size(); ++i) {
    int lca = LCA(vec[i], vec[i + 1]);
    T[lca].emplace_back(vec[i + 1], sumw[vec[i + 1]] - sumw[lca]);
    T[vec[i + 1]].emplace_back(lca, sumw[vec[i + 1]] - sumw[lca]);
  }
  for (auto x : vec)
    if (!vis[x])
      a[x] = 1e18;
}

void solve(std::vector<int> &vec) {
  build(vec);
  rt2 = 0, getsz2(vec[0], 0), getrt2(vec[0], 0, sz2[vec[0]]), dfs2(rt2);

  for (auto x : vec) T[x].clear(), T[x].shrink_to_fit();
}

void dfs1(int u) {
  a[u] = 0, _dfs1(u, 0);
  solve(idx1);
  for (auto x : idx1) a[x] = vis[x] = del2[x] = 0;
  idx1.clear(), idx1.shrink_to_fit();
  del1[u] = 1;
  for (auto [v, w] : G1[u]) {
    if (del1[v]) continue;
    rt1 = 0, getsz1(v, 0), getrt1(v, 0, sz1[v]), dfs1(v);
  }
}

void dickdreamer() {
  std::cin >> n;
  for (int i = 1; i < n; ++i) {
    int u, v, w;
    std::cin >> u >> v >> w;
    G1[u].emplace_back(v, w), G1[v].emplace_back(u, w);
  }
  for (int i = 1; i < n; ++i) {
    int u, v, w;
    std::cin >> u >> v >> w;
    G2[u].emplace_back(v, w), G2[v].emplace_back(u, w);
  }
  prework();
  std::fill_n(ans + 1, n, 1e18);
  mx1[0] = mx2[0] = 1e9, getsz1(1, 0), getrt1(1, 0, n), dfs1(1);
  for (int i = 1; i <= n; ++i) std::cout << ans[i] << '\n';
}

int32_t main() {
#ifdef ORZXKR
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
#endif
  std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
  int T = 1;
  // std::cin >> T;
  while (T--) dickdreamer();
  // std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
  return 0;
}

详细

Test #1:

score: 0
Time Limit Exceeded

input:

250000
137466 116241 624409157
188961 163586 148491970
13958 122239 46409636
186120 44010 919858866
72320 102560 92679302
158544 236582 882613876
22331 114267 646741536
210782 42861 679450428
56693 45397 898958944
71188 114724 904191407
15203 225401 210626781
31071 144225 278121829
110354 83972 4557...

output:


result: