QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#330081 | #8055. Balance | ucup-team635# | RE | 0ms | 2176kb | Rust | 11.0kb | 2024-02-17 12:07:59 | 2024-02-17 12:07:59 |
Judging History
answer
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];
for e in e.iter_mut() {
e.0 = sc.next::<usize>() - 1;
e.1 = sc.next::<usize>() - 1;
}
let a: Vec<usize> = sc.next_vec(n);
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()];
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();
tree[a].push(b);
tree[b].push(a);
}
}
let g = tree;
let mut hist = vec![0; n + 1];
for a in a.iter() {
hist[*a] += 1;
}
hist.retain(|h| *h > 0);
hist.insert(0, 0);
for i in 1..hist.len() {
hist[i] += hist[i - 1];
}
let mut z = a.clone();
z.sort();
z.dedup();
let (hist, z) = (hist, z);
let mut inv = vec![None; n + 1];
for i in 1..hist.len() {
inv[hist[i]] = Some(i);
}
let mut topo = vec![0];
let mut parent = vec![None; g.len()];
for i in 0..g.len() {
let v = topo[i];
for u in g[v].clone() {
if Some(u) != parent[v] {
topo.push(u);
parent[u] = Some(v);
}
}
}
let (parent, topo) = (parent, topo);
let mut dp = vec![0; g.len()];
let mut size = vertex.iter().map(|v| dsu.size(*v)).collect::<Vec<_>>();
for &v in topo.iter().rev() {
let mut val = 0;
for &u in g[v].iter() {
if parent[v] == Some(u) {
continue;
}
val = val.max(dp[u]);
if let Some(k) = inv[size[u]] {
if dp[u] == k - 1 {
val = val.max(k);
}
}
size[v] += size[u];
}
dp[v] = val;
}
let mut up = vec![0; g.len()];
for &v in topo.iter() {
let mut child = g[v].clone();
child.retain(|c| parent[*c] == Some(v));
let mut val = up[v];
let mut memo = vec![val];
for &u in child.iter() {
val.chmax(dp[u]);
if let Some(k) = inv[size[u]] {
if dp[u] == k - 1 {
val = val.max(k);
}
}
memo.push(val);
}
let left = memo;
let mut val = up[v];
let mut memo = vec![val];
for &u in child.iter().rev() {
val.chmax(dp[u]);
if let Some(k) = inv[size[u]] {
if dp[u] == k - 1 {
val = val.max(k);
}
}
memo.push(val);
}
let right = memo;
for (i, &u) in child.iter().enumerate() {
let mut val = left[i].max(right[right.len() - 2 - i]);
if let Some(k) = inv[n - size[u]] {
if val == k - 1 {
val = k;
}
}
up[u] = val;
}
}
let mut v = vertex.len();
for i in 0..g.len() {
if dp[i] == z.len() - 1 || up[i] == z.len() - 1 {
v = i;
}
}
if v == vertex.len() {
writeln!(out, "No").ok();
continue;
}
let root = v;
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 = vertex.iter().map(|v| dsu.size(*v)).collect::<Vec<_>>();
for &v in topo.iter().rev() {
let mut val = 0;
for &u in g[v].iter() {
val = val.max(dp[u]);
if let Some(k) = inv[size[u]] {
if dp[u] == k - 1 {
val = val.max(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 e.iter() {
if dsu.same(a, b) {
continue;
}
let x = dsu.root(a);
let y = dsu.root(b);
let s = vertex.binary_search(&x).unwrap();
let t = vertex.binary_search(&y).unwrap();
let mut update = false;
if let Some(&v) = del.get(&(s, t)) {
value[x] = z[v];
update = true;
}
if let Some(&v) = del.get(&(t, s)) {
value[y] = z[v];
update = true;
}
if !update {
add.push((x, y));
}
}
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]);
}
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 2176kb
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 1 2 3 4 5 No Yes 2 1 2 2 3 Yes 2 2 1 1 1 No
result:
ok ok (5 test cases)
Test #2:
score: -100
Runtime Error
input:
100000 4 3 4 2 1 3 2 1 2 1 3 2 5 7 2 5 5 3 2 3 5 1 4 3 2 4 4 3 1 3 1 1 2 3 2 2 1 2 3 1 1 1 4 7 3 4 1 4 2 3 4 3 4 2 3 1 4 3 2 3 3 2 4 6 2 4 3 1 1 2 1 2 2 3 4 2 1 1 3 3 4 7 3 2 4 2 1 2 3 4 3 2 2 4 3 4 2 1 1 1 5 5 3 2 1 5 4 5 4 3 2 1 1 2 2 3 2 3 5 2 3 1 3 3 1 3 1 2 1 3 2 3 2 3 2 1 2 1 1 2 1 1 2 3 2 1 1...
output:
Yes 2 2 1 3 No Yes 1 1 1 No No Yes 2 1 1 1 No No Yes 1 1 Yes 1 1 Yes 1 1 Yes 1 1 1 1 No Yes 1 1 1 1 1