QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#253623#7790. 最短路求和hos_lyric#10 50ms33516kbC++1412.7kb2023-11-17 10:27:162024-07-04 02:25:57

Judging History

This is the latest submission verdict.

  • [2024-07-04 02:25:57]
  • Judged
  • Verdict: 10
  • Time: 50ms
  • Memory: 33516kb
  • [2023-11-17 10:27:16]
  • Submitted

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")


struct Hld {
  int n, rt;
  // needs to be tree
  // vertex lists
  // modified in build(rt) (parent removed, heavy child first)
  vector<vector<int>> graph;
  vector<int> sz, par, dep;
  int zeit;
  vector<int> dis, fin, sid;
  // head vertex (minimum depth) in heavy path
  vector<int> head;

  Hld() : n(0), rt(-1), zeit(0) {}
  explicit Hld(int n_) : n(n_), rt(-1), graph(n), zeit(0) {}
  void ae(int u, int v) {
    assert(0 <= u); assert(u < n);
    assert(0 <= v); assert(v < n);
    graph[u].push_back(v);
    graph[v].push_back(u);
  }

  void dfsSz(int u) {
    sz[u] = 1;
    for (const int v : graph[u]) {
      auto it = std::find(graph[v].begin(), graph[v].end(), u);
      if (it != graph[v].end()) graph[v].erase(it);
      par[v] = u;
      dep[v] = dep[u] + 1;
      dfsSz(v);
      sz[u] += sz[v];
    }
  }
  void dfsHld(int u) {
    dis[u] = zeit++;
    const int deg = graph[u].size();
    if (deg > 0) {
      int vm = graph[u][0];
      int jm = 0;
      for (int j = 1; j < deg; ++j) {
        const int v = graph[u][j];
        if (sz[vm] < sz[v]) {
          vm = v;
          jm = j;
        }
      }
      swap(graph[u][0], graph[u][jm]);
      head[vm] = head[u];
      dfsHld(vm);
      for (int j = 1; j < deg; ++j) {
        const int v = graph[u][j];
        head[v] = v;
        dfsHld(v);
      }
    }
    fin[u] = zeit;
  }
  void build(int rt_) {
    assert(0 <= rt_); assert(rt_ < n);
    rt = rt_;
    sz.assign(n, 0);
    par.assign(n, -1);
    dep.assign(n, -1);
    dep[rt] = 0;
    dfsSz(rt);
    zeit = 0;
    dis.assign(n, -1);
    fin.assign(n, -1);
    head.assign(n, -1);
    head[rt] = rt;
    dfsHld(rt);
    assert(zeit == n);
    sid.assign(n, -1);
    for (int u = 0; u < n; ++u) sid[dis[u]] = u;
  }

  friend ostream &operator<<(ostream &os, const Hld &hld) {
    const int maxDep = *max_element(hld.dep.begin(), hld.dep.end());
    vector<string> ss(2 * maxDep + 1);
    int pos = 0, maxPos = 0;
    for (int j = 0; j < hld.n; ++j) {
      const int u = hld.sid[j];
      const int d = hld.dep[u];
      if (hld.head[u] == u) {
        if (j != 0) {
          pos = maxPos + 1;
          ss[2 * d - 1].resize(pos, '-');
          ss[2 * d - 1] += '+';
        }
      } else {
        ss[2 * d - 1].resize(pos, ' ');
        ss[2 * d - 1] += '|';
      }
      ss[2 * d].resize(pos, ' ');
      ss[2 * d] += std::to_string(u);
      if (maxPos < static_cast<int>(ss[2 * d].size())) {
        maxPos = ss[2 * d].size();
      }
    }
    for (int d = 0; d <= 2 * maxDep; ++d) os << ss[d] << '\n';
    return os;
  }

  bool contains(int u, int v) const {
    return (dis[u] <= dis[v] && dis[v] < fin[u]);
  }
  int lca(int u, int v) const {
    assert(0 <= u); assert(u < n);
    assert(0 <= v); assert(v < n);
    for (; head[u] != head[v]; ) (dis[u] > dis[v]) ? (u = par[head[u]]) : (v = par[head[v]]);
    return (dis[u] > dis[v]) ? v : u;
  }
  int jumpUp(int u, int d) const {
    assert(0 <= u); assert(u < n);
    assert(d >= 0);
    if (dep[u] < d) return -1;
    const int tar = dep[u] - d;
    for (u = head[u]; ; u = head[par[u]]) {
      if (dep[u] <= tar) return sid[dis[u] + (tar - dep[u])];
    }
  }
  int jump(int u, int v, int d) const {
    assert(0 <= u); assert(u < n);
    assert(0 <= v); assert(v < n);
    assert(d >= 0);
    const int l = lca(u, v);
    const int du = dep[u] - dep[l], dv = dep[v] - dep[l];
    if (d <= du) {
      return jumpUp(u, d);
    } else if (d <= du + dv) {
      return jumpUp(v, du + dv - d);
    } else {
      return -1;
    }
  }
  // [u, v) or [u, v]
  template <class F> void doPathUp(int u, int v, bool inclusive, F f) const {
    assert(contains(v, u));
    for (; head[u] != head[v]; u = par[head[u]]) f(dis[head[u]], dis[u] + 1);
    if (inclusive) {
      f(dis[v], dis[u] + 1);
    } else {
      if (v != u) f(dis[v] + 1, dis[u] + 1);
    }
  }
  // not path order, include lca(u, v) or not
  template <class F> void doPath(int u, int v, bool inclusive, F f) const {
    const int l = lca(u, v);
    doPathUp(u, l, false, f);
    doPathUp(v, l, inclusive, f);
  }

  // (vs, ps): compressed tree
  // vs: DFS order (sorted by dis)
  // vs[ps[x]]: the parent of vs[x]
  // ids[vs[x]] = x, not set for non-tree vertex
  vector<int> ids;
  pair<vector<int>, vector<int>> compress(vector<int> us) {
    // O(n) first time
    ids.resize(n, -1);
    std::sort(us.begin(), us.end(), [&](int u, int v) -> bool {
      return (dis[u] < dis[v]);
    });
    us.erase(std::unique(us.begin(), us.end()), us.end());
    int usLen = us.size();
    assert(usLen >= 1);
    for (int x = 1; x < usLen; ++x) us.push_back(lca(us[x - 1], us[x]));
    std::sort(us.begin(), us.end(), [&](int u, int v) -> bool {
      return (dis[u] < dis[v]);
    });
    us.erase(std::unique(us.begin(), us.end()), us.end());
    usLen = us.size();
    for (int x = 0; x < usLen; ++x) ids[us[x]] = x;
    vector<int> ps(usLen, -1);
    for (int x = 1; x < usLen; ++x) ps[x] = ids[lca(us[x - 1], us[x])];
    return make_pair(us, ps);
  }
};

////////////////////////////////////////////////////////////////////////////////


vector<int> uf;
int root(int u) {
  return (uf[u] < 0) ? u : (uf[u] = root(uf[u]));
}
bool connect(int u, int v) {
  u = root(u);
  v = root(v);
  if (u == v) return false;
  if (uf[u] > uf[v]) swap(u, v);
  uf[u] += uf[v];
  uf[v] = u;
  return true;
}


constexpr Int INF = 1001001001001001001LL;

int N, M;
vector<int> A, B;
vector<Int> C;

Hld hld;
vector<Int> cs;
vector<int> colors;
Int ans;
int dfsInside(int color, int tot, int u) {
  int sz = 1;
  for (const int v : hld.graph[u]) if (colors[v] == color) {
    const int res = dfsInside(color, tot, v);
    ans += (Int)(tot - res) * res * (cs[v] - cs[u]);
    sz += res;
  }
  return sz;
}

int main() {
  for (; ~scanf("%d%d", &N, &M); ) {
    A.resize(M);
    B.resize(M);
    C.resize(M);
    for (int i = 0; i < M; ++i) {
      scanf("%d%d%lld", &A[i], &B[i], &C[i]);
      --A[i];
      --B[i];
    }
    
    uf.assign(N, -1);
    vector<int> mst(M, 0);
    for (int i = 0; i < M; ++i) {
      if (connect(A[i], B[i])) {
        mst[i] = 1;
      }
    }
    hld = Hld(N);
    for (int i = 0; i < M; ++i) if (mst[i]) {
      hld.ae(A[i], B[i]);
    }
    hld.build(0);
    
    cs.assign(N, 0);
    for (int i = 0; i < M; ++i) if (mst[i]) {
      cs[(hld.dis[A[i]] < hld.dis[B[i]]) ? B[i] : A[i]] = C[i];
    }
    for (int j = 1; j < N; ++j) {
      const int u = hld.sid[j];
      cs[u] += cs[hld.par[u]];
    }
    
    vector<int> critical;
    critical.push_back(0);
    for (int i = 0; i < M; ++i) if (!mst[i]) {
      critical.push_back(A[i]);
      critical.push_back(B[i]);
    }
    const auto vsps = hld.compress(critical);
// cerr<<"mst = "<<mst<<endl;
// cerr<<"cs = "<<cs<<endl;
// cerr<<"critical = "<<critical<<endl;
// cerr<<"vsps = "<<vsps<<endl;
// cerr<<"ids = "<<hld.ids<<endl;
    
    const int K = vsps.first.size();
    vector<vector<pair<Int, int>>> gra(K);
    auto ae = [&](int x, int y, Int c) -> void {
// cerr<<"ae "<<x<<" "<<y<<" "<<c<<endl;
      gra[x].emplace_back(c, y);
      gra[y].emplace_back(c, x);
    };
    for (int y = 1; y < K; ++y) {
      const int x = vsps.second[y];
      ae(x, y, cs[vsps.first[y]] - cs[vsps.first[x]]);
    }
    for (int i = 0; i < M; ++i) if (!mst[i]) {
      ae(hld.ids[A[i]], hld.ids[B[i]], C[i]);
    }
    vector<vector<Int>> dist(K, vector<Int>(K, INF));
    for (int s = 0; s < K; ++s) {
      using Entry = pair<Int, int>;
      priority_queue<Entry, vector<Entry>, greater<Entry>> que;
      que.emplace(dist[s][s] = 0, s);
      for (; !que.empty(); ) {
        const Int c = que.top().first;
        const int u = que.top().second;
        que.pop();
        if (dist[s][u] == c) {
          for (const auto &edge : gra[u]) {
            const Int cc = c + edge.first;
            const int v = edge.second;
            if (chmin(dist[s][v], cc)) {
              que.emplace(cc, v);
            }
          }
        }
      }
// cerr<<"dist["<<s<<"] = "<<dist[s]<<endl;
    }
    
    colors.assign(N, -1);
    ans = 0;
    
    /*
      [x] <- ... <- [y]
      uss[y]: ((dist to [x], dist to [y]))
      near [y] first
    */
    vector<int> near(N, -1);
    for (int y = 1; y < K; ++y) {
      const int x = vsps.second[y];
      for (int u = vsps.first[y]; u != vsps.first[x]; u = hld.par[u]) {
        near[u] = u;
      }
    }
    near[0] = 0;
    vector<vector<int>> uss(N);
    for (int j = 0; j < N; ++j) {
      const int u = hld.sid[j];
      if (!~near[u]) {
        near[u] = near[hld.par[u]];
      }
      uss[near[u]].push_back(u);
    }
// cerr<<"near = "<<near<<endl;
// cerr<<"uss = "<<uss<<endl;
    vector<int> isVirLeaf(K, 1);
    for (int y = 1; y < K; ++y) {
      const int x = vsps.second[y];
      isVirLeaf[x] = 0;
    }
    vector<vector<pair<Int, Int>>> fss(K);
    for (int y = 0; y < K; ++y) {
      const int x = y ? vsps.second[y] : 0;
      auto &fs = fss[y];
      for (int u = vsps.first[y]; ; u = hld.par[u]) {
        if (y && u == vsps.first[x]) break;
        const Int cx = cs[u] - cs[vsps.first[x]];
        const Int cy = cs[vsps.first[y]] - cs[u];
        for (const int v : uss[u]) {
          fs.emplace_back(cx + (cs[v] - cs[u]), cy + (cs[v] - cs[u]));
          colors[v] = y;
        }
        if (u == vsps.first[x]) break;
      }
// cerr<<"fss["<<y<<"] = "<<fs<<endl;
      const int tot = fs.size();
      if (tot) {
        const int res = dfsInside(y, tot, vsps.first[x]);
        assert(tot == (y ? (res - 1) : res));
      }
    }
// cerr<<"colors = "<<colors<<endl;
// cerr<<"inside: "<<ans<<endl;
    
    // [0, p): [y] is better, [y, $): [x] is better
    vector<int> lens(K);
    vector<vector<Int>> sumXss(K), sumYss(K);
    for (int y = 0; y < K; ++y) {
      lens[y] = fss[y].size();
      sumXss[y].assign(lens[y] + 1, 0);
      sumYss[y].assign(lens[y] + 1, 0);
      for (int p = lens[y]; --p >= 0; ) sumXss[y][p] = fss[y][p].first + sumXss[y][p + 1];
      for (int p = 0; p < lens[y]; ++p) sumYss[y][p + 1] = sumYss[y][p] + fss[y][p].second;
    }
    
    for (int y0 = 0; y0 < K; ++y0) for (int y1 = y0 + 1; y1 < K; ++y1) {
      const int x0 = y0 ? vsps.second[y0] : 0;
      const int x1 = y1 ? vsps.second[y1] : 0;
      int p1 = 0;
      for (int p0 = 0; p0 < lens[y0]; ++p0) {
        const Int cx1 = min(fss[y0][p0].first + dist[x0][x1], fss[y0][p0].second + dist[y0][x1]);
        const Int cy1 = min(fss[y0][p0].first + dist[x0][y1], fss[y0][p0].second + dist[y0][y1]);
        for (; p1 > 0 && cx1 + fss[y1][p1 - 1].first < cy1 + fss[y1][p1 - 1].second; --p1) {}
        for (; p1 < lens[y1] && cx1 + fss[y1][p1].first > cy1 + fss[y1][p1].second; ++p1) {}
        Int here = 0;
        here += ((lens[y1] - p1) * cx1 + sumXss[y1][p1]);
        here += (p1 * cy1 + sumYss[y1][p1]);
// cerr<<y0<<" "<<y1<<" "<<fss[y0][p0]<<": "<<here<<endl;
        ans += here;
      }
    }
    
    printf("%lld\n", ans);
#ifdef LOCAL
vector<vector<Int>>d(N,vector<Int>(N,INF));
for(int u=0;u<N;++u)d[u][u]=0;
for(int i=0;i<M;++i){chmin(d[A[i]][B[i]],C[i]);chmin(d[B[i]][A[i]],C[i]);}
for(int w=0;w<N;++w)for(int u=0;u<N;++u)for(int v=0;v<N;++v)chmin(d[u][v],d[u][w]+d[w][v]);
Int brt=0;
for(int u=0;u<N;++u)for(int v=u+1;v<N;++v)brt+=d[u][v];
cerr<<"brt = "<<brt<<endl;
assert(brt==ans);
#endif
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Wrong Answer

Test #1:

score: 10
Accepted
time: 16ms
memory: 4712kb

input:

300 1300
90 125 9397
157 77 3704
197 112 8218
152 235 1702
271 107 5600
117 92 1401
104 61 2242
127 230 1471
91 116 2740
29 127 4326
151 78 2569
273 241 7487
170 115 3100
152 171 2504
193 95 5921
30 281 1309
285 262 6462
100 265 8151
200 90 277
237 151 1123
231 219 974
238 176 2239
89 147 2256
233 2...

output:

324731073

result:

ok single line: '324731073'

Test #2:

score: 10
Accepted
time: 1ms
memory: 4088kb

input:

300 299
168 161 181
71 254 4119
160 298 8533
148 29 4098
277 279 73
204 174 644
230 113 1265
89 194 6883
296 21 1759
280 190 4793
298 86 3667
185 67 7427
163 257 7845
15 54 8936
52 22 2786
154 199 5543
136 278 4548
256 27 9557
147 34 4208
255 292 1753
242 300 619
263 37 2565
215 109 866
75 153 4924
...

output:

3693554127

result:

ok single line: '3693554127'

Test #3:

score: 10
Accepted
time: 1ms
memory: 3880kb

input:

300 299
278 277 2650
247 246 4859
110 111 138
293 294 3261
261 262 4054
85 84 6692
135 136 2929
154 153 9014
295 296 8688
212 213 7459
233 234 1563
63 64 9100
123 122 6289
275 274 3781
98 97 530
18 17 2851
261 260 260
61 62 1601
143 142 588
174 175 4724
105 104 2084
285 286 6458
75 76 3094
186 185 6...

output:

21433726951

result:

ok single line: '21433726951'

Test #4:

score: 0
Wrong Answer
time: 1ms
memory: 3836kb

input:

300 300
275 55 6088
139 229 1932
106 297 9861
186 220 3110
146 202 634
270 269 2005
22 233 4461
108 139 7146
11 246 8665
187 236 417
90 9 7925
95 211 7057
7 147 4672
38 63 5056
18 22 7299
60 34 7068
155 114 4061
141 128 4442
266 185 2635
221 187 4869
96 243 6720
87 227 8371
70 196 3403
175 290 3159
...

output:

3860479483

result:

wrong answer 1st lines differ - expected: '3860396713', found: '3860479483'

Subtask #2:

score: 10
Accepted

Test #5:

score: 10
Accepted
time: 37ms
memory: 33516kb

input:

100000 99999
54625 54626 7146
20763 20764 300
41530 41531 9968
37448 37449 7434
81056 81055 700
27731 27730 8783
12408 12409 514
90652 90653 99
84104 84105 2524
83093 83094 195
17757 17756 2560
81925 81926 8935
14220 14219 9619
25516 25515 5883
89413 89412 275
46936 46937 3997
82755 82754 2775
53080...

output:

834269687204155387

result:

ok single line: '834269687204155387'

Test #6:

score: 10
Accepted
time: 47ms
memory: 21652kb

input:

100000 99999
13706 21290 3420
3037 78334 3887
94743 35121 9291
67873 91038 345
48348 12825 56
25237 56325 19
44215 92806 6788
40110 98929 5038
43250 87034 907
19698 18774 44
79406 51075 9523
79992 15613 4062
91111 66707 1595
1223 12300 3924
65613 22546 9008
24856 20394 393
14915 86273 5876
39594 160...

output:

4573680940298584

result:

ok single line: '4573680940298584'

Subtask #3:

score: 0
Wrong Answer

Test #7:

score: 0
Wrong Answer
time: 50ms
memory: 21920kb

input:

100000 100000
35241 48789 5098
4546 39869 6127
31415 22834 6026
25703 1952 6807
86143 78951 3421
34193 9615 4329
31012 98959 1664
81244 37874 3542
600 74315 9939
91066 57088 2111
5064 33313 9799
78834 28718 1133
41687 82171 4214
44801 87500 4238
40150 73606 5172
17787 30281 3718
52715 82529 4419
924...

output:

3317591356537732

result:

wrong answer 1st lines differ - expected: '3317259529562659', found: '3317591356537732'

Subtask #4:

score: 0
Skipped

Dependency #2:

100%
Accepted

Dependency #3:

0%

Subtask #5:

score: 0
Skipped

Dependency #4:

0%

Subtask #6:

score: 0
Skipped

Dependency #1:

0%