結果
| 問題 |
No.922 東北きりきざむたん
|
| コンテスト | |
| ユーザー |
akakimidori
|
| 提出日時 | 2019-11-09 03:48:48 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 6,146 bytes |
| コンパイル時間 | 13,184 ms |
| コンパイル使用メモリ | 378,304 KB |
| 実行使用メモリ | 26,676 KB |
| 最終ジャッジ日時 | 2024-09-15 03:55:40 |
| 合計ジャッジ時間 | 16,686 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge6 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 25 WA * 1 |
ソースコード
// ---------- begin Lowest Common Ancestor ----------
struct LCA {
graph: Vec<Vec<usize>>,
path_root: Vec<usize>,
path_parent: Vec<usize>,
index: Vec<usize>
}
impl LCA {
fn new(n: usize) -> Self {
LCA {
graph: vec![vec![]; n],
path_root: vec![],
path_parent: vec![],
index: vec![],
}
}
fn add_edge(&mut self, a: usize, b: usize) {
self.graph[a].push(b);
self.graph[b].push(a);
}
fn build(&mut self, root: usize) {
let mut q = vec![];
let mut stack = vec![(root, root)];
let graph = &mut self.graph;
while let Some((v, p)) = stack.pop() {
q.push(v);
for i in 0..graph[v].len() {
if graph[v][i] == p {
graph[v].swap_remove(i);
break;
}
}
for &u in &graph[v] {
stack.push((u, v));
}
}
let n = graph.len();
let mut size = vec![1; n];
for &v in q.iter().rev() {
for i in 0..graph[v].len() {
let u = graph[v][i];
size[v] += size[u];
if size[u] > size[graph[v][0]] {
graph[v].swap(0, i);
}
}
}
let mut path_root = vec![root; n];
let mut path_parent = vec![root; n];
let mut index = vec![n; n];
let mut stack = vec![root];
let mut k = 0;
while let Some(v) = stack.pop() {
index[v] = k;
k += 1;
for i in 1..graph[v].len() {
let u = graph[v][i];
path_root[u] = u;
path_parent[u] = v;
stack.push(u);
}
if graph[v].len() > 0 {
let u = graph[v][0];
path_root[u] = path_root[v];
path_parent[u] = path_parent[v];
stack.push(u);
}
}
self.path_root = path_root;
self.path_parent = path_parent;
self.index = index;
}
fn query(&self, mut a: usize, mut b: usize) -> usize {
let path = &self.path_root;
let parent = &self.path_parent;
let index = &self.index;
while path[a] != path[b] {
if index[a] < index[b] {
b = parent[b];
} else {
a = parent[a];
}
}
if index[a] < index[b] {a} else {b}
}
}
// ---------- end Lowest Common Ancestor ----------
//---------- begin union_find ----------
#[allow(dead_code)]
mod union_find {
pub struct UF {
p: Vec<i32>,
}
impl UF {
pub fn new(n: usize) -> UF {
UF {p: vec![-1; n] }
}
pub fn init(&mut self) {
for p in self.p.iter_mut() {
*p = -1;
}
}
pub fn root(&mut self, mut x: usize) -> usize {
while self.p[x] >= 0 {
x = self.p[x] as usize;
}
x
}
pub fn same(&mut self, x: usize, y: usize) -> bool {
self.root(x) == self.root(y)
}
pub fn unite(&mut self, mut x: usize, mut y: usize) -> Option<(usize, usize)> {
x = self.root(x);
y = self.root(y);
if x == y {
return None;
}
if self.p[x] > self.p[y] {
let s = x;
x = y;
y = s;
}
self.p[x] += self.p[y];
self.p[y] = x as i32;
Some((x, y))
}
pub fn get_size(&mut self, x: usize) -> usize {
let r = self.root(x);
(-self.p[r]) as usize
}
}
}
//---------- end union_find ----------
use std::io::Read;
fn run() {
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
let mut it = s.trim().split_whitespace();
let n: usize = it.next().unwrap().parse().unwrap();
let m: usize = it.next().unwrap().parse().unwrap();
let query: usize = it.next().unwrap().parse().unwrap();
let mut g = vec![vec![]; n + 1];
let mut u = union_find::UF::new(n + 1);
let mut lca = LCA::new(n + 1);
for _ in 0..m {
let a: usize = it.next().unwrap().parse().unwrap();
let b: usize = it.next().unwrap().parse().unwrap();
g[a].push(b);
g[b].push(a);
lca.add_edge(a, b);
u.unite(a, b);
}
for i in 1..=n {
if i == u.root(i) {
g[0].push(i);
lca.add_edge(0, i);
}
}
lca.build(0);
let mut q = vec![];
let mut stack = vec![(0, 0)];
let mut depth = vec![0; n + 1];
while let Some((v, p)) = stack.pop() {
q.push(v);
for i in 0..g[v].len() {
if g[v][i] == p {
g[v].remove(i);
break;
}
}
for &u in &g[v] {
depth[u] = depth[v] + 1;
stack.push((u, v));
}
}
let mut cnt = vec![0; n + 1];
let mut ans = 0;
for _ in 0..query {
let a: usize = it.next().unwrap().parse().unwrap();
let b: usize = it.next().unwrap().parse().unwrap();
if u.same(a, b) {
ans += depth[a] + depth[b] - 2 * depth[lca.query(a, b)];
} else {
cnt[a] += 1;
cnt[b] += 1;
}
}
let mut down = vec![0; n + 1];
let mut size = cnt.clone();
for &v in q[1..].iter().rev() {
for &u in &g[v] {
down[v] += down[u] + size[u];
size[v] += size[u];
}
}
let mut dp = down.clone();
let all_size = size.clone();
for &v in &q[1..] {
let r = u.root(v);
let d = dp[v];
for &u in &g[v] {
dp[u] = d - size[u] + all_size[r] - size[u];
}
}
for v in 1..=n {
let r = u.root(v);
dp[r] = std::cmp::min(dp[r], dp[v]);
}
for v in 1..=n {
if u.root(v) == v {
ans += dp[v];
}
}
println!("{}", ans);
}
fn main() {
run();
}
akakimidori