QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#253621 | #7790. 最短路求和 | hos_lyric# | 10 | 46ms | 33488kb | C++14 | 12.4kb | 2023-11-17 10:19:51 | 2024-07-04 02:25:55 |
Judging History
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];
{
int u = vsps.first[y];
if (!isVirLeaf[y]) {
u = hld.par[u];
}
for (; ~u; u = hld.par[u]) {
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;
// cerr<<"colors = "<<colors<<endl;
const int tot = fs.size();
if (tot) {
const int res = dfsInside(y, tot, vsps.first[x]);
assert(tot == res);
}
}
// cerr<<"ans = "<<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);
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Subtask #1:
score: 0
Wrong Answer
Test #1:
score: 0
Wrong Answer
time: 12ms
memory: 4680kb
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:
640660067
result:
wrong answer 1st lines differ - expected: '324731073', found: '640660067'
Subtask #2:
score: 10
Accepted
Test #5:
score: 10
Accepted
time: 42ms
memory: 33488kb
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: 0
Accepted
time: 40ms
memory: 21736kb
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: 46ms
memory: 21792kb
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:
3317631599939685
result:
wrong answer 1st lines differ - expected: '3317259529562659', found: '3317631599939685'
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%