1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include <bits/stdc++.h> using namespace std; constexpr int MAXN = 3e5 + 5; int n, m, q, diameter; array<int, MAXN> sz, belong, dis, dia; vector<int> G[MAXN], vec[MAXN]; vector<long long> sum[MAXN];
void dfs1(int cur, int fa, int& p) { for (auto& to : G[cur]) { if (to == fa) continue; dis[to] = dis[cur] + 1; if (dis[to] > diameter) diameter = dis[to], p = to; dfs1(to, cur, p); } } void dfs2(int cur, int fa, int tot) { sz[tot]++, belong[cur] = tot; for (auto& to : G[cur]) { if (to == fa) continue; dfs2(to, cur, tot); } } void dfs3(int cur, int fa, int d) { dis[cur] = max(dis[cur], d); for (auto& to : G[cur]) { if (to == fa) continue; dfs3(to, cur, d + 1); } } map<pair<int, int>, double> mp; void query(int u, int v) { if (u == v) { cout << "-1\n"; return; } if (sz[u] > sz[v]) swap(u, v); if (mp.count({u, v})) { cout << mp[{u, v}] << "\n"; return; } double res = 0; int tmp = max(dia[u], dia[v]); for (auto& i : vec[u]) { int pos = upper_bound(vec[v].begin(), vec[v].end(), tmp - 1 - i) - vec[v].begin(); res += 1LL * tmp * pos; res += 1LL * (i + 1) * (sum[v].size() - pos); res += sum[v][sum[v].size() - 1] - (pos ? sum[v][pos - 1] : 0); } res /= 1LL * sz[u] * sz[v]; cout << (mp[{u, v}] = res) << "\n"; } void init() { int tot = 0; for (int i = 1; i <= n; i++) { if (!belong[i]) { int st = i, ed = i; diameter = 0, dis[i] = 0, dfs1(i, 0, st); diameter = 0, dis[st] = 0, dfs1(st, 0, ed); dfs2(i, 0, ++tot), dia[tot] = diameter; dfs3(st, 0, 0), dfs3(ed, 0, 0); } } for (int i = 1; i <= n; i++) vec[belong[i]].push_back(dis[i]); for (int i = 1; i <= tot; i++) { sort(vec[i].begin(), vec[i].end()); sum[i].resize(vec[i].size()); sum[i][0] = vec[i][0]; for (int j = 1; j < vec[i].size(); j++) sum[i][j] = sum[i][j - 1] + vec[i][j]; } } int main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cout << setprecision(6) << fixed; cin >> n >> m >> q; for (int i = 1, u, v; i <= m; i++) { cin >> u >> v; G[u].push_back(v), G[v].push_back(u); } init(); for (int i = 1, u, v; i <= q; i++) { cin >> u >> v; query(belong[u], belong[v]); } return 0; }
|