結果
| 問題 |
No.922 東北きりきざむたん
|
| コンテスト | |
| ユーザー |
🍮かんプリン
|
| 提出日時 | 2019-11-08 22:50:17 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,490 bytes |
| コンパイル時間 | 2,803 ms |
| コンパイル使用メモリ | 189,764 KB |
| 実行使用メモリ | 24,624 KB |
| 最終ジャッジ日時 | 2024-09-15 02:00:35 |
| 合計ジャッジ時間 | 8,468 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 4 WA * 21 TLE * 1 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:128:24: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
128 | int u, v; scanf("%d %d", &u, &v);
| ~~~~~^~~~~~~~~~~~~~~~~
main.cpp:148:24: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
148 | int a, b; scanf("%d %d", &a, &b);
| ~~~~~^~~~~~~~~~~~~~~~~
ソースコード
#include "bits/stdc++.h"
#define REP(i, n) for(int i = 0; i < int(n); i++)
#define FOR(i,n,m) for(int i = int(n); i < int(m); i++)
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int INF = 1e9 + 6;
const ll LLINF = 1e18 + 1;
// 最近共通祖先(Doubling)
// verrify : https://onlinejudge.u-aizu.ac.jp/problems/GRL_5_C
// <O(NlogN),O(lonN)>
struct LowestCommonAncestor {
private:
int n;
int log;
vector<vector<int>> parent;
vector<int> dep;
//vector<ll> dis; // root からの距離
void dfs(const vector<vector<int>> &G, int v, int p, int d) {
parent[0][v] = p;
dep[v] = d;
//dis[v] = di;
for (int to : G[v]) {
if (to != p) dfs(G, to, v, d + 1);
//if (e.to != p) dfs(G, e.to, v, d + 1,di + e.cost);
}
}
public:
LowestCommonAncestor(const vector<vector<int>> &G, int root = 0) {
build(G, root);
}
void build(const vector<vector<int>> &G, int root = 0) {
n = G.size();
log = log2(n) + 1;
parent.resize(log, vector<int>(n));
dep.resize(n);
//dis.resize(n);
dfs(G, root, -1, 0);
for (int k = 0; k + 1 < log; k++) {
for (int v = 0; v < G.size(); v++) {
if (parent[k][v] < 0) {
parent[k + 1][v] = -1;
}
else {
parent[k + 1][v] = parent[k][parent[k][v]];
}
}
}
}
int depth(int v) {
return dep[v];
}
// O(logN)
int lca(int u, int v) {
if (dep[u] > dep[v]) swap(u, v);
REP(k, log) if ((dep[v] - dep[u]) >> k & 1) v = parent[k][v];
if (u == v) return u;
for (int k = log - 1; k >= 0; k--) {
if (parent[k][u] != parent[k][v]) {
u = parent[k][u];
v = parent[k][v];
}
}
return parent[0][u];
}
int dist(int u, int v) {
return dep[u] + dep[v] - 2 * dep[lca(u, v)];
//return dis[u] + dis[v] - 2 * dis[lca(u, v)];
}
};
// UnionFind
class UnionFind {
private:
vector<int> par;
public:
UnionFind(int n) {
par.resize(n, -1);
}
int root(int x) {
if (par[x] < 0) return x;
return par[x] = root(par[x]);
}
bool unite(int x, int y) {
int rx = root(x);
int ry = root(y);
if (rx == ry) return false;
if (size(rx) < size(ry)) swap(rx, ry);
par[rx] += par[ry];
par[ry] = rx;
return true;
}
bool same(int x, int y) {
int rx = root(x);
int ry = root(y);
return rx == ry;
}
int size(int x) {
return -par[root(x)];
}
};
ll dfs(int v,int depth, const vector<vector<int>> &G, vector<int> &cnt) {
ll res = (ll)cnt[v] * depth;
for (auto u : G[v]) {
res += dfs(u, depth+1,G, cnt);
}
return res;
}
int main() {
int n, m, q; cin >> n >> m >> q;
UnionFind uni(n);
vector<vector<int>> G(n);
vector<vector<int>> T(n);
vector<bool> linked(n,false);
REP(i, m) {
int u, v; scanf("%d %d", &u, &v);
u--; v--;
uni.unite(u, v);
G[u].push_back(v);
G[v].push_back(u);
T[u].push_back(v);
T[v].push_back(u);
}
REP(i, n) {
if (uni.same(0, i)) continue;
if (linked[uni.root(i)]) continue;
linked[uni.root(i)] = true;
T[uni.root(0)].push_back(uni.root(i));
T[uni.root(i)].push_back(uni.root(0));
}
LowestCommonAncestor lca(T);
ll ans = 0;
vector<int> cnt(n);
map<int, int> mp;
REP(i, q) {
int a, b; scanf("%d %d", &a, &b);
a--; b--;
if (uni.same(a, b)) {
ans += lca.dist(a, b);
continue;
}
cnt[a]++;
cnt[b]++;
if (cnt[mp[uni.root(a)]] < cnt[a]) {
mp[uni.root(a)] = a;
}
if (cnt[mp[uni.root(b)]] < cnt[b]) {
mp[uni.root(b)] = b;
}
}
struct ttt {
int a, b, c;
};
for (auto p : mp) {
queue<ttt> que;
que.push({p.second, -1, 0});
while (!que.empty()) {
auto pp = que.front(); que.pop();
ans += (ll)cnt[pp.a] * pp.c;
for (auto v : G[pp.a]) {
if (v == pp.b) continue;
que.push({v,pp.a,pp.c + 1});
}
}
}
cout << ans << endl;
return 0;
}
🍮かんプリン