QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#330106 | #8055. Balance | ucup-team635# | WA | 0ms | 2148kb | Rust | 13.1kb | 2024-02-17 12:31:28 | 2024-02-17 12:31:29 |
Judging History
answer
// ---------- begin Rerooting ----------
pub trait RerootingOperator {
type Value: Clone;
type Edge: Clone;
fn init(&mut self, v: usize) -> Self::Value;
fn merge(&mut self, p: &Self::Value, c: &Self::Value, e: &Self::Edge) -> Self::Value;
}
pub struct Rerooting<R: RerootingOperator> {
manager: R,
size: usize,
edge: Vec<(usize, usize, R::Edge, R::Edge)>,
}
impl<R: RerootingOperator> Rerooting<R> {
pub fn new(size: usize, manager: R) -> Self {
assert!(size > 0 && size < 10usize.pow(8));
Rerooting {
manager: manager,
size: size,
edge: vec![],
}
}
pub fn add_edge(&mut self, a: usize, b: usize, cost: R::Edge) {
assert!(a < self.size && b < self.size && a != b);
self.add_edge_bi(a, b, cost.clone(), cost);
}
pub fn add_edge_bi(&mut self, a: usize, b: usize, ab: R::Edge, ba: R::Edge) {
assert!(a < self.size && b < self.size && a != b);
self.edge.push((a, b, ab, ba));
}
pub fn solve(&mut self) -> Vec<R::Value> {
let size = self.size;
let mut graph = vec![vec![]; size];
for e in self.edge.iter() {
graph[e.0].push((e.1, e.2.clone()));
graph[e.1].push((e.0, e.3.clone()));
}
let root = 0;
let mut topo = vec![root];
let mut parent = vec![root; size];
let mut parent_edge: Vec<Option<R::Edge>> = (0..size).map(|_| None).collect();
for i in 0..size {
let v = topo[i];
let child = std::mem::take(&mut graph[v]);
for e in child.iter() {
let k = graph[e.0].iter().position(|e| e.0 == v).unwrap();
let c = graph[e.0].remove(k).1;
parent_edge[e.0] = Some(c);
parent[e.0] = v;
topo.push(e.0);
}
graph[v] = child;
}
let manager = &mut self.manager;
let mut down: Vec<_> = (0..size).map(|v| manager.init(v)).collect();
for &v in topo.iter().rev() {
for e in graph[v].iter() {
down[v] = manager.merge(&down[v], &down[e.0], &e.1);
}
}
let mut up: Vec<_> = (0..size).map(|v| manager.init(v)).collect();
let mut stack = vec![];
for &v in topo.iter() {
if let Some(e) = parent_edge[v].take() {
let ini = manager.init(v);
up[v] = manager.merge(&ini, &up[v], &e);
}
if !graph[v].is_empty() {
stack.push((graph[v].as_slice(), up[v].clone()));
while let Some((g, val)) = stack.pop() {
if g.len() == 1 {
up[g[0].0] = val;
} else {
let m = g.len() / 2;
let (a, b) = g.split_at(m);
for a in [(a, b), (b, a)].iter() {
let mut p = val.clone();
for a in a.0.iter() {
p = manager.merge(&p, &down[a.0], &a.1);
}
stack.push((a.1, p));
}
}
}
}
for e in graph[v].iter() {
up[v] = manager.merge(&up[v], &down[e.0], &e.1);
}
}
up
}
}
// ---------- end Rerooting ----------
mod util {
pub trait Join {
fn join(self, sep: &str) -> String;
}
impl<T, I> Join for I
where
I: Iterator<Item = T>,
T: std::fmt::Display,
{
fn join(self, sep: &str) -> String {
let mut s = String::new();
use std::fmt::*;
for (i, v) in self.enumerate() {
if i > 0 {
write!(&mut s, "{}", sep).ok();
}
write!(&mut s, "{}", v).ok();
}
s
}
}
}
// ---------- begin chmin, chmax ----------
pub trait ChangeMinMax {
fn chmin(&mut self, x: Self) -> bool;
fn chmax(&mut self, x: Self) -> bool;
}
impl<T: PartialOrd> ChangeMinMax for T {
fn chmin(&mut self, x: Self) -> bool {
*self > x && {
*self = x;
true
}
}
fn chmax(&mut self, x: Self) -> bool {
*self < x && {
*self = x;
true
}
}
}
// ---------- end chmin, chmax ----------
// ---------- begin quick find ----------
pub struct QuickFind {
size: usize,
id: Vec<usize>,
list: Vec<Vec<usize>>,
}
impl QuickFind {
pub fn new(size: usize) -> Self {
let id = (0..size).collect::<Vec<_>>();
let list = (0..size).map(|x| vec![x]).collect::<Vec<_>>();
QuickFind { size, id, list }
}
pub fn root(&self, x: usize) -> usize {
assert!(x < self.size);
self.id[x]
}
pub fn same(&self, x: usize, y: usize) -> bool {
assert!(x < self.size);
assert!(y < self.size);
self.root(x) == self.root(y)
}
pub fn unite(&mut self, x: usize, y: usize) -> Option<(usize, usize)> {
assert!(x < self.size);
assert!(y < self.size);
let mut x = self.root(x);
let mut y = self.root(y);
if x == y {
return None;
}
if (self.list[x].len(), x) < (self.list[y].len(), y) {
std::mem::swap(&mut x, &mut y);
}
let mut z = std::mem::take(&mut self.list[y]);
z.iter().for_each(|y| self.id[*y] = x);
self.list[x].append(&mut z);
Some((x, y))
}
pub fn enumerate(&self, x: usize) -> &[usize] {
assert!(x < self.size);
&self.list[self.root(x)]
}
pub fn size(&self, x: usize) -> usize {
assert!(x < self.size);
self.enumerate(x).len()
}
}
// ---------- end quick find ----------
// ---------- begin scannner ----------
#[allow(dead_code)]
mod scanner {
use std::str::FromStr;
pub struct Scanner<'a> {
it: std::str::SplitWhitespace<'a>,
}
impl<'a> Scanner<'a> {
pub fn new(s: &'a String) -> Scanner<'a> {
Scanner {
it: s.split_whitespace(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
self.it.next().unwrap().parse::<T>().ok().unwrap()
}
pub fn next_bytes(&mut self) -> Vec<u8> {
self.it.next().unwrap().bytes().collect()
}
pub fn next_chars(&mut self) -> Vec<char> {
self.it.next().unwrap().chars().collect()
}
pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> {
(0..len).map(|_| self.next()).collect()
}
}
}
// ---------- end scannner ----------
use std::collections::*;
use std::io::Write;
type Map<K, V> = BTreeMap<K, V>;
type Set<T> = BTreeSet<T>;
type Deque<T> = VecDeque<T>;
fn main() {
use std::io::Read;
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
let mut sc = scanner::Scanner::new(&s);
let out = std::io::stdout();
let mut out = std::io::BufWriter::new(out.lock());
run(&mut sc, &mut out);
}
fn run<W: Write>(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<W>) {
let t: u32 = sc.next();
for _ in 0..t {
let n: usize = sc.next();
let m: usize = sc.next();
let mut e = vec![(0, 0); m];
let mut test = QuickFind::new(n);
for e in e.iter_mut() {
e.0 = sc.next::<usize>() - 1;
e.1 = sc.next::<usize>() - 1;
test.unite(e.0, e.1);
}
let a: Vec<usize> = sc.next_vec(n);
if test.size(0) != n {
writeln!(out, "No").ok();
continue;
}
let mut g = vec![vec![]; n];
for (i, &(a, b)) in e.iter().enumerate() {
g[a].push((b, i));
g[b].push((a, i));
}
let mut ord = vec![n; n];
let mut low = vec![n; n];
let mut id = 0;
dfs(0, m, &g, &mut ord, &mut low, &mut id);
let mut dsu = QuickFind::new(n);
for (x, y) in ord.iter().zip(low.iter()) {
dsu.unite(*x, *y);
}
drop(g);
drop(ord);
drop(low);
let vertex = (0..n).filter(|v| *v == dsu.root(*v)).collect::<Vec<_>>();
let mut tree = vec![vec![]; vertex.len()];
let mut edge = vec![];
for &(a, b) in e.iter() {
if dsu.root(a) != dsu.root(b) {
let a = vertex.binary_search(&dsu.root(a)).unwrap();
let b = vertex.binary_search(&dsu.root(b)).unwrap();
edge.push((a, b));
tree[a].push(b);
tree[b].push(a);
}
}
let g = tree;
let mut z = a.clone();
z.sort();
z.dedup();
let z = z;
let mut hist = vec![0; z.len() + 1];
for a in a.iter() {
let x = z.binary_search(a).unwrap();
hist[x + 1] += 1;
}
for i in 1..hist.len() {
hist[i] += hist[i - 1];
}
let hist = hist;
let mut inv = vec![None; n + 1];
for i in 1..hist.len() {
inv[hist[i]] = Some(i);
}
let inv = inv;
let size = vertex.iter().map(|v| dsu.size(*v)).collect::<Vec<_>>();
let info = Info {
inv: inv.clone(),
size: size.clone(),
};
let mut solver = Rerooting::new(vertex.len(), info);
for &(a, b) in edge.iter() {
solver.add_edge(a, b, ());
}
let res = solver.solve();
let v = (0..res.len()).find(|v| res[*v].1 == z.len() - 1);
if v.is_none() {
writeln!(out, "No").ok();
continue;
}
let root = v.unwrap();
let mut g = g;
let mut topo = vec![root];
for i in 0..g.len() {
let v = topo[i];
for u in g[v].clone() {
g[u].retain(|p| *p != v);
topo.push(u);
}
}
let mut size = size;
let mut dp = vec![0; g.len()];
for &v in topo.iter().rev() {
let mut val = 0;
for &u in g[v].iter() {
val.chmax(dp[u]);
if let Some(k) = inv[size[u]] {
if dp[u] == k - 1 {
val.chmax(k);
}
}
size[v] += size[u];
}
dp[v] = val;
}
let mut del = Map::new();
let mut pos = root;
while dp[pos] > 0 {
let mut update = false;
for &u in g[pos].iter() {
if dp[u] == dp[pos] {
pos = u;
update = true;
break;
} else if inv[size[u]].map_or(false, |k| dp[u] == k - 1 && dp[pos] == k) {
del.insert((pos, u), dp[pos]);
pos = u;
update = true;
break;
}
}
assert!(update);
}
let mut value = vec![z[0]; n];
let mut add = vec![];
for &(a, b) in edge.iter() {
let mut update = false;
if let Some(&v) = del.get(&(a, b)) {
value[a] = z[v];
update = true;
}
if let Some(&v) = del.get(&(b, a)) {
value[b] = z[v];
update = true;
}
if !update {
add.push((a, b));
}
}
for (a, b) in add {
let (p, c) = dsu.unite(a, b).unwrap();
if value[c] != z[0] {
value[p] = value[c];
}
}
writeln!(out, "Yes").ok();
use util::*;
writeln!(out, "{}", (0..n).map(|v| value[dsu.root(v)]).join(" ")).ok();
}
}
fn dfs(
v: usize,
prev: usize,
g: &[Vec<(usize, usize)>],
ord: &mut [usize],
low: &mut [usize],
id: &mut usize,
) {
ord[v] = *id;
low[v] = *id;
*id += 1;
for &(u, k) in g[v].iter().filter(|e| e.1 != prev) {
if ord[u] > *id {
dfs(u, k, g, ord, low, id);
low[v] = low[v].min(low[u]);
} else {
low[v] = low[v].min(ord[u]);
}
}
}
struct Info {
inv: Vec<Option<usize>>,
size: Vec<usize>,
}
impl RerootingOperator for Info {
// size, value
type Value = (usize, usize);
type Edge = ();
fn init(&mut self, v: usize) -> Self::Value {
(self.size[v], 0)
}
fn merge(&mut self, p: &Self::Value, c: &Self::Value, e: &Self::Edge) -> Self::Value {
let size = p.0 + c.0;
let mut val = p.1.max(c.1);
if let Some(k) = self.inv[c.0] {
if c.1 == k - 1 {
val = val.max(k);
}
}
(size, val)
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 2148kb
input:
5 5 4 1 2 2 3 3 4 4 5 1 2 3 4 5 5 4 1 2 1 3 1 4 1 5 1 2 3 4 5 5 4 1 2 1 3 1 4 1 5 1 2 2 2 3 5 6 1 2 1 2 2 3 3 4 4 5 3 5 1 2 1 2 1 2 2 1 2 1 2 1 2
output:
Yes 5 4 3 2 1 No Yes 2 3 1 2 2 Yes 1 1 1 1 1 No
result:
wrong answer 4-th smallest numbers are not same (test case 4)