結果
| 問題 |
No.922 東北きりきざむたん
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-11-08 21:55:05 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 141 ms / 2,000 ms |
| コード長 | 4,268 bytes |
| コンパイル時間 | 2,467 ms |
| コンパイル使用メモリ | 194,920 KB |
| 実行使用メモリ | 27,452 KB |
| 最終ジャッジ日時 | 2024-09-15 01:27:19 |
| 合計ジャッジ時間 | 5,829 ms |
|
ジャッジサーバーID (参考情報) |
judge6 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 26 |
ソースコード
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define repr(i, n) for (int i = (n) - 1; i >= 0; i--)
#define repe(i, l, r) for (int i = (l); i < (r); i++)
#define reper(i, l, r) for (int i = (r) - 1; i >= (l); i--)
#define repi(i, l, r) for (int i = (l); i <= (r); i++)
#define repir(i, l, r) for (int i = (r); i >= (l); i--)
#define range(a) a.begin(), a.end()
void init_io() { std::cin.tie(nullptr); std::ios::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(15); }
using namespace std;
using ll = long long;
struct unionfind {
vector<int> dat;
unionfind(int n) : dat(n, -1) {}
int find(int x) {
if (dat[x] < 0) return x;
return dat[x] = find(dat[x]);
}
void unite(int x, int y) {
x = find(x);
y = find(y);
if (x == y) return;
if (dat[x] > dat[y]) swap(x, y);
dat[x] += dat[y];
dat[y] = x;
}
int size(int x) {
return -dat[find(x)];
}
};
struct HLD {
vector<int> label, parent, head, depth;
template<class graph>
HLD(const graph &g) : label(g.size(), -1), parent(g.size()), head(g.size()), depth(g.size()) {
const int n = g.size();
vector<int> size(n);
auto dfs = [&](auto dfs, int u, int p) -> void {
size[u] = 1;
for (int v : g[u]) if (v != p) {
depth[v] = depth[u] + 1;
dfs(dfs, v, u);
size[u] += size[v];
}
};
rep(i, n) {
if (size[i] == 0) dfs(dfs, i, -1);
}
int k = 0;
auto dfs2 = [&](auto dfs, int u, int p, int h) -> void {
label[u] = k++;
head[u] = h;
parent[u] = p;
for (int v : g[u]) if (v != p && size[v] * 2 > size[u]) dfs(dfs, v, u, h);
for (int v : g[u]) if (v != p && size[v] * 2 <= size[u]) dfs(dfs, v, u, v);
};
rep(i, n) {
if (label[i] == -1) dfs2(dfs2, i, -1, i);
}
}
int lca(int u, int v) {
for (;;) {
if (label[u] > label[v]) swap(u, v);
if (head[u] == head[v]) return u;
v = parent[head[v]];
}
}
template<class F> void each(int u, int v, F f) {
for (;;) {
if (label[u] > label[v]) swap(u, v);
if (head[u] == head[v]) {
f(label[u], label[v]);
return;
}
f(label[head[v]], label[v]);
v = parent[head[v]];
}
}
template<class F> void each_edge(int u, int v, F f) {
for (;;) {
if (label[u] > label[v]) swap(u, v);
if (head[u] == head[v]) {
if (u != v) f(label[u] + 1, label[v]);
return;
}
f(label[head[v]], label[v]);
v = parent[head[v]];
}
}
int dist(int u, int v) {
return depth[u] + depth[v] - 2 * depth[lca(u, v)];
}
int operator[](int u) {
return label[u];
};
};
int main() { init_io();
int N, M, Q; cin >> N >> M >> Q;
vector<vector<int>> G(N);
unionfind uf(N);
rep(i, M) {
int u, v; cin >> u >> v; u--; v--;
G[u].push_back(v);
G[v].push_back(u);
uf.unite(u, v);
}
HLD hld(G);
vector<int> cnt(N);
ll ans = 0;
rep(i, Q) {
int a, b; cin >> a >> b; a--; b--;
if (uf.find(a) == uf.find(b)) {
ans += hld.dist(a, b);
} else {
cnt[a]++;
cnt[b]++;
}
}
vector<int> roots;
rep(i, N) if (uf.find(i) == i) roots.push_back(i);
vector<ll> dist(N);
vector<ll> size(N);
auto dfs = [&](auto dfs, int u, int p) -> void {
size[u] = cnt[u];
for (int v : G[u]) if (v != p) {
dfs(dfs, v, u);
dist[u] += dist[v] + size[v];
size[u] += size[v];
}
};
for (int r : roots) dfs(dfs, r, -1);
vector<ll> dist2(N);
auto dfs2 = [&](auto dfs2, int u, int p) -> void {
dist[u] = 0;
size[u] = cnt[u];
for (int v : G[u]) {
dist[u] += dist[v] + size[v];
size[u] += size[v];
}
dist2[u] = dist[u];
for (int v : G[u]) if (v != p) {
ll tmp_dist = dist[u];
ll tmp_size = size[u];
dist[u] -= dist[v] + size[v];
size[u] -= size[v];
dfs2(dfs2, v, u);
dist[u] = tmp_dist;
size[u] = tmp_size;
}
};
for (int r : roots) dfs2(dfs2, r, -1);
map<int, ll> mp;
rep(i, N) {
int r = uf.find(i);
if (mp.count(r)) {
mp[r] = min(mp[r], dist2[i]);
} else {
mp[r] = dist2[i];
}
}
for (auto kv : mp) ans += kv.second;
cout << ans << endl;
}