QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#298468 | #7790. 最短路求和 | zyc070419 | 0 | 0ms | 0kb | C++14 | 7.7kb | 2024-01-06 10:46:57 | 2024-01-06 10:46:58 |
Judging History
answer
#include <bits/stdc++.h>
#define INF 2e9
#define ll long long
using namespace std;
const int N = 1e5 + 3;
const int M = N + 1005;
const int CN = 2005;
const int CM = 3005;
inline int read() {
char ch = getchar(); int x = 0;
while (!isdigit(ch)) {ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();}
return x;
}
struct node {
int x, y, v;
}e[M];
struct Node {
int x, disl, disr;
Node(int a = 0, int b = 0, int c = 0) {x = a; disl = b; disr = c;}
};
ll ans, pdis[N], sdis[N];
int n, m, cnt, id[N], du[N], sz[N], qu[CN], mem[CN][CN], pcnt[N], scnt[N];
map<int, int> mp[N];
vector< pair<int, int> > g[N], G[N], E;
queue<int> q;
vector<Node> vec[CN][CN];
priority_queue< pair<int, int> > pq;
bitset<CN> in;
void dij(int st) {
in.reset();
for (int i = 1; i <= cnt; ++i) mem[st][i] = INF;
mem[st][st] = 0; pq.push(make_pair(-mem[st][st], st));
while (!pq.empty()) {
int x = pq.top().second; pq.pop();
if (in[x]) continue;
in[x] = true;
for (auto tmp : G[x]) {
int y = tmp.first;
if (mem[st][y] > mem[st][x] + tmp.second) {
mem[st][y] = mem[st][x] + tmp.second;
pq.push(make_pair(-mem[st][y], y));
}
}
}
}
int main() {
n = read(); m = read();
for (int i = 1; i <= n; ++i) sz[i] = 1;
for (int i = 1, x, y, v; i <= m; ++i) {
x = read(); y = read(); v = read();
if (mp[x].count(y) && e[mp[x][y]].v <= v) continue;
else if (!mp[x].count(y)) du[x]++, du[y]++;
e[i].x = x; e[i].y = y; e[i].v = v;
mp[x][y] = mp[y][x] = i;
}
for (int i = 1; i <= n; ++i)
if (du[i] <= 1) q.push(i);
while (!q.empty()) {
int x = q.front(); q.pop();
if (du[x] == 0) continue;
else {
int y = (*mp[x].begin()).first, i = mp[x][y];
mp[x].erase(y); mp[y].erase(x);
du[x]--; du[y]--;
if (du[y] <= 1) q.push(y);
ans += 1ll * sz[x] * sz[y] * e[i].v;
sz[x] += sz[y];
}
}
for (int x = 1; x <= n; ++x)
for (auto tmp : mp[x])
g[x].push_back(make_pair(tmp.first, e[tmp.second].v));
for (int x = 1; x <= n; ++x) {
if (du[x] == 2) continue;
id[x] = ++cnt; qu[cnt] = x;
}
vector< pair<int, int> > tmp;
for (int i = 1; i <= cnt; ++i) {
int x = qu[i];
for (auto o : g[x]) {
tmp.clear();
int y = o.first, sum = o.second;
while (du[y] == 2) {
pair<int, int> now;
if (g[y][0].first == tmp.back().first) now = g[y][1];
else now = g[y][0];
tmp.push_back(make_pair(y, sum));
sum += now.second;
y = now.first;
}
if (id[x] > id[y]) continue;
G[id[x]].push_back(make_pair(id[y], sum));
G[id[y]].push_back(make_pair(id[x], sum));
E.push_back(make_pair(id[x], id[y]));
for (auto p : tmp) vec[id[x]][id[y]].push_back(Node(p.first, p.second, sum - p.second));
}
}
for (int i = 1; i <= cnt; ++i) dij(i);
for (int i = 2; i <= cnt; ++i)
for (int j = 1; j < i; ++j)
ans += 1ll * sz[qu[i]] * sz[qu[j]] * mem[i][j];
for (int i = 1; i <= cnt; ++i)
for (auto j : E) for (auto y : vec[j.first][j.second])
ans += 1ll * sz[qu[i]] * sz[y.x] * min(mem[i][j.first] + y.disl, mem[i][j.second] + y.disr);
for (auto i : E) {
int l = i.first, r = i.second;
if (vec[l][r].empty()) continue;
int cntup = 0; ll disup = 0;
int cntdn = 0; ll disdn = 0;
int p = 0;
for (int j = 0; j < vec[l][r].size(); ++j) {
while (p < vec[l][r].size() && vec[l][r][j].disl - vec[l][r][p].disl > vec[l][r][j].disr + vec[l][r][p].disl + mem[l][r]) {
cntup += sz[vec[l][r][p].x]; disup += 1ll * sz[vec[l][r][p].x] * vec[l][r][p].disl;
cntdn -= sz[vec[l][r][p].x]; disdn -= 1ll * sz[vec[l][r][p].x] * vec[l][r][p].disl;
p++;
}
ans += 1ll * sz[vec[l][r][j].x] * (1ll * cntup * (mem[l][r] + vec[l][r][j].disr) + disup);
ans += 1ll * sz[vec[l][r][j].x] * (1ll * cntdn * vec[l][r][j].disl - disdn);
cntdn += sz[vec[l][r][j].x]; disdn += 1ll * sz[vec[l][r][j].x] * vec[l][r][j].disl;
}
}
for (int idi = 0; idi < E.size(); ++idi) {
auto i = E[idi];
int li = i.first, ri = i.second;
if (vec[li][ri].empty()) continue;
pcnt[0] = sz[vec[li][ri][0].x];
pdis[0] = 1ll * sz[vec[li][ri][0].x] * vec[li][ri][0].disl;
for (int p = 1; p < vec[li][ri].size(); ++p) {
pcnt[p] = pcnt[p - 1] + sz[vec[li][ri][p].x];
pdis[p] = pdis[p - 1] + 1ll * sz[vec[li][ri][p].x] * vec[li][ri][p].disl;
}
scnt[vec[li][ri].size()] = sdis[vec[li][ri].size()] = 0;
for (int p = vec[li][ri].size() - 1; p >= 0; --p) {
scnt[p] = scnt[p + 1] + sz[vec[li][ri][p].x];
sdis[p] = sdis[p + 1] + 1ll * sz[vec[li][ri][p].x] * vec[li][ri][p].disr;
}
for (int idj = idi + 1; idj < E.size(); ++idj) {
auto j = E[idj];
int lj = i.first, rj = j.second;
if (vec[lj][rj].empty()) continue;
int p = 0;
while (p < vec[lj][rj].size() && vec[lj][rj][p].disl + mem[li][lj] < vec[lj][rj][p].disr + mem[li][rj]) p++;
int q = 0;
while (q < vec[lj][rj].size() && vec[lj][rj][p].disl + mem[ri][lj] < vec[lj][rj][p].disr + mem[ri][rj]) p++;
int cnt; ll sum;
cnt = 0; sum = 0;
for (int k = 0; k < min(p, q); ++k) {
cnt += sz[vec[lj][rj][k].x];
sum += 1ll * sz[vec[lj][rj][k].x] * vec[lj][rj][k].disl;
}
auto check = [&](int l, int r, int oo, int lim) {return vec[l][r][oo].disr - vec[l][r][oo].disl >= lim;};
auto find = [&](int l, int r, int lim) {
if (!check(l, r, 0, lim)) return -1;
int L = 0, R = vec[l][r].size() - 1, mid;
while (L + 1 < R) {
mid = (L + R) >> 1;
if (check(l, r, mid, lim)) L = mid;
else R = mid;
}
if (check(l, r, R, lim)) return R;
else return L;
};
int o = find(li, ri, mem[li][lj] - mem[ri][lj]);
ans += 1ll * pcnt[o] * cnt * mem[li][lj];
ans += 1ll * pcnt[o] * sum + 1ll * pdis[o] * cnt;
ans += 1ll * scnt[o + 1] * cnt * mem[ri][lj];
ans += 1ll * scnt[o + 1] * sum + 1ll * sdis[o + 1] * cnt;
if (p < q) {
int K = 0;
for (int k = p; k < q; ++k) {
while (K < vec[li][ri].size()) {
int len1 = vec[li][ri][K].disl + mem[li][rj] + vec[lj][rj][k].disr;
int len2 = vec[li][ri][K].disr + mem[ri][lj] + vec[lj][rj][k].disl;
if (len1 >= len2) break;
K++;
}
if (K) {
ans += 1ll * pcnt[K - 1] * sz[vec[lj][rj][k].x] * mem[li][rj];
ans += 1ll * pcnt[K - 1] * sz[vec[lj][rj][k].x] * vec[lj][rj][k].disr;
ans += 1ll * pdis[K - 1] * sz[vec[lj][rj][k].x];
}
ans += 1ll * scnt[K] * sz[vec[lj][rj][k].x] * mem[ri][lj];
ans += 1ll * scnt[K] * sz[vec[lj][rj][k].x] * vec[lj][rj][k].disl;
ans += 1ll * sdis[K] * sz[vec[lj][rj][k].x];
}
}else {
int K = vec[li][ri].size() - 1;
for (int k = q; k < p; ++k) {
while (K >= 0) {
int len1 = vec[li][ri][K].disr + mem[ri][rj] + vec[lj][rj][k].disr;
int len2 = vec[li][ri][K].disl + mem[li][lj] + vec[lj][rj][k].disl;
if (len1 >= len2) break;
K--;
}
if (K >= 0) {
ans += 1ll * pcnt[K] * sz[vec[lj][rj][k].x] * mem[li][lj];
ans += 1ll * pcnt[K] * sz[vec[lj][rj][k].x] * vec[lj][rj][k].disl;
ans += 1ll * pdis[K] * sz[vec[lj][rj][k].x];
}
ans += 1ll * scnt[K + 1] * sz[vec[lj][rj][k].x] * mem[ri][rj];
ans += 1ll * scnt[K + 1] * sz[vec[lj][rj][k].x] * vec[lj][rj][k].disr;
ans += 1ll * sdis[K + 1] * sz[vec[lj][rj][k].x];
}
}
cnt = 0; sum = 0;
for (int k = max(p, q); k < vec[lj][rj].size(); ++k) {
cnt += sz[vec[lj][rj][k].x];
sum += 1ll * sz[vec[lj][rj][k].x] * vec[lj][rj][k].disr;
}
o = find(li, ri, mem[li][rj] - mem[ri][rj]);
ans += 1ll * pcnt[o] * cnt * mem[li][rj];
ans += 1ll * pcnt[o] * sum + 1ll * pdis[o] * cnt;
ans += 1ll * scnt[o + 1] * cnt * mem[ri][rj];
ans += 1ll * scnt[o + 1] * sum + 1ll * sdis[o + 1] * cnt;
}
}
return printf("%lld\n", ans), 0;
}
詳細信息
Subtask #1:
score: 0
Runtime Error
Test #1:
score: 0
Runtime Error
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:
result:
Subtask #2:
score: 0
Time Limit Exceeded
Test #5:
score: 0
Time Limit Exceeded
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:
result:
Subtask #3:
score: 0
Time Limit Exceeded
Test #7:
score: 0
Time Limit Exceeded
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:
result:
Subtask #4:
score: 0
Skipped
Dependency #2:
0%
Subtask #5:
score: 0
Skipped
Dependency #4:
0%
Subtask #6:
score: 0
Skipped
Dependency #1:
0%