結果
問題 | No.2987 Colorful University of Tree |
ユーザー | akakimidori |
提出日時 | 2024-12-12 19:21:20 |
言語 | Rust (1.77.0 + proconio) |
結果 |
AC
|
実行時間 | 1,036 ms / 5,000 ms |
コード長 | 8,404 bytes |
コンパイル時間 | 17,488 ms |
コンパイル使用メモリ | 379,092 KB |
実行使用メモリ | 131,648 KB |
最終ジャッジ日時 | 2024-12-12 19:22:52 |
合計ジャッジ時間 | 44,964 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,248 KB |
testcase_02 | AC | 150 ms
5,248 KB |
testcase_03 | AC | 166 ms
5,248 KB |
testcase_04 | AC | 167 ms
5,248 KB |
testcase_05 | AC | 640 ms
75,940 KB |
testcase_06 | AC | 108 ms
24,396 KB |
testcase_07 | AC | 120 ms
21,892 KB |
testcase_08 | AC | 728 ms
79,972 KB |
testcase_09 | AC | 124 ms
24,516 KB |
testcase_10 | AC | 898 ms
110,896 KB |
testcase_11 | AC | 973 ms
102,616 KB |
testcase_12 | AC | 897 ms
131,648 KB |
testcase_13 | AC | 1,036 ms
102,608 KB |
testcase_14 | AC | 1,014 ms
105,964 KB |
testcase_15 | AC | 969 ms
120,076 KB |
testcase_16 | AC | 945 ms
114,516 KB |
testcase_17 | AC | 919 ms
107,440 KB |
testcase_18 | AC | 943 ms
102,832 KB |
testcase_19 | AC | 960 ms
105,956 KB |
testcase_20 | AC | 1,000 ms
102,636 KB |
testcase_21 | AC | 961 ms
102,672 KB |
testcase_22 | AC | 474 ms
102,740 KB |
testcase_23 | AC | 736 ms
131,408 KB |
testcase_24 | AC | 249 ms
13,224 KB |
testcase_25 | AC | 284 ms
13,228 KB |
testcase_26 | AC | 246 ms
13,224 KB |
testcase_27 | AC | 246 ms
13,224 KB |
testcase_28 | AC | 243 ms
13,224 KB |
testcase_29 | AC | 10 ms
5,248 KB |
testcase_30 | AC | 69 ms
5,248 KB |
testcase_31 | AC | 63 ms
5,248 KB |
testcase_32 | AC | 135 ms
5,888 KB |
testcase_33 | AC | 175 ms
16,344 KB |
testcase_34 | AC | 220 ms
26,268 KB |
testcase_35 | AC | 230 ms
57,108 KB |
testcase_36 | AC | 441 ms
96,576 KB |
testcase_37 | AC | 55 ms
16,064 KB |
testcase_38 | AC | 219 ms
52,480 KB |
testcase_39 | AC | 49 ms
14,780 KB |
testcase_40 | AC | 364 ms
81,240 KB |
99_evil_hack_000.txt | AC | 1 ms
5,248 KB |
コンパイルメッセージ
warning: unused variable: `u` --> src/main.rs:233:32 | 233 | for (&color, &(dp, u, k)) in buf.iter().zip(child_color.iter()) { | ^ help: if this is intentional, prefix it with an underscore: `_u` | = note: `#[warn(unused_variables)]` on by default warning: type alias `Deque` is never used --> src/main.rs:81:6 | 81 | type Deque<T> = VecDeque<T>; | ^^^^^ | = note: `#[warn(dead_code)]` on by default
ソースコード
fn rand_memory() -> usize { Box::into_raw(Box::new("I hope this is a random number")) as usize } fn rand() -> usize { static mut X: usize = 0; unsafe { if X == 0 { X = rand_memory(); } X ^= X << 13; X ^= X >> 17; X ^= X << 5; X } } fn shuffle<T>(a: &mut [T]) { for i in 1..a.len() { let p = rand() % (i + 1); a.swap(i, p); } } 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 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 mut e = vec![vec![]; n]; for e in e.iter_mut() { let m = sc.next::<usize>(); e.resize(m, 0usize); for e in e.iter_mut() { *e = sc.next::<usize>() - 1; } } let (q, vc, ec) = solve(e.clone()); let mut list = vec![vec![]; n - 1]; for (e, ec) in e.iter().zip(ec.iter()) { for (e, ec) in e.iter().zip(ec.iter()) { list[*e].push(*ec); } } assert!(list.iter().all(|l| l[0] != l[1])); let mut set = Set::new(); writeln!(out, "{}", q).ok(); for (vc, ec) in vc.iter().zip(ec.iter()) { for &c in ec.iter() { assert!(set.insert((vc, c))); } use util::*; writeln!(out, "{} {}", *vc + 1, ec.iter().map(|a| *a + 1).join(" ")).ok(); } } } fn solve(e: Vec<Vec<usize>>) -> (usize, Vec<usize>, Vec<Vec<usize>>) { let n = e.len(); let mut list = vec![vec![]; n - 1]; for (i, e) in e.iter().enumerate() { for (j, e) in e.iter().enumerate() { list[*e].push((i, j)); } } let mut tree = vec![vec![]; n]; for (i, v) in list.iter().enumerate() { let (a, b) = (v[0].0, v[1].0); tree[a].push((b, i)); tree[b].push((a, i)); } let deg = e.iter().map(|e| e.len()).collect::<Vec<_>>(); let root = (0..n).max_by_key(|v| deg[*v]).unwrap(); let mut topo = vec![root]; let mut parent = vec![n; n]; for i in 0..n { let v = topo[i]; for (u, k) in tree[v].clone() { parent[u] = k; tree[u].retain(|p| p.0 != v); topo.push(u); } } let (list, tree, topo, parent) = (list, tree, topo, parent); let mut q = (1..) .find(|&p| p * p >= 2 * (n - 1)) .unwrap() .max(*deg.iter().max().unwrap()); if greedy(°, q).is_none() { q += 1; } let q = q; let vc = greedy(°, q).unwrap(); let mut memo = vec![vec![]; q]; for (i, vc) in vc.iter().enumerate() { memo[*vc].push(i); } let mut ans = vec![]; while { let mut used = vec![false; q]; let mut color_list = vec![vec![]; n]; for memo in memo.iter() { let sum = memo.iter().map(|v| deg[*v]).sum::<usize>(); if 2 * sum <= q { for &v in memo.iter() { let mut c = vec![0; deg[v]]; for c in c.iter_mut() { let mut x = rand() % q; while used[x] { x = rand() % q; } *c = x; used[x] = true; } color_list[v] = c; } for x in memo.iter().flat_map(|v| color_list[*v].iter()) { used[*x] = false; } } else { let mut perm = (0..q).collect::<Vec<_>>(); shuffle(&mut perm); for &v in memo.iter() { let mut c = vec![0; deg[v]]; for c in c.iter_mut() { *c = perm.pop().unwrap(); } color_list[v] = c; } } } let mut tmp = e.iter().map(|e| vec![q; e.len()]).collect::<Vec<_>>(); let mut dp = vec![q; n]; for &v in topo.iter().rev() { let mut child_color = vec![]; for &(u, k) in tree[v].iter() { child_color.push((dp[u], u, k)); } child_color.sort(); let mut pos = Map::new(); for (i, &(c, _, _)) in child_color.iter().enumerate() { pos.entry(c).or_insert((i, i)).1 = i; } let mut clist = std::mem::take(&mut color_list[v]); let mut buf = vec![!0; clist.len()]; let mut range = (0, clist.len()); for c in clist.iter_mut() { if let Some(&(l, r)) = pos.get(c) { range.0 = range.0.max(r - l + 1); buf[l] = *c; *c = !0; } } if v == root && range.0 == range.1 { break; } assert!(range.0 < range.1); clist.retain(|c| *c != !0); for buf in buf.iter_mut() { if *buf == !0 { *buf = clist.pop().unwrap(); } } let shift = rand() % (range.1 - range.0) + range.0; buf.rotate_right(shift); for (&color, &(dp, u, k)) in buf.iter().zip(child_color.iter()) { assert!(dp != color); let pos = list[k].iter().find(|p| p.0 == v).unwrap().1; tmp[v][pos] = color; } if v != root { let c = buf.pop().unwrap(); dp[v] = c; let k = parent[v]; let pos = list[k].iter().find(|p| p.0 == v).unwrap().1; tmp[v][pos] = c; } if v == root { ans = tmp; break; } } ans.is_empty() } {} (q, vc, ans) } fn greedy(a: &[usize], q: usize) -> Option<Vec<usize>> { let n = a.len(); assert!(a.iter().sum::<usize>() == 2 * (n - 1)); let mut rem = vec![q; q]; let mut h = std::collections::BinaryHeap::new(); for i in 0..q { h.push((q, i)); } let mut ans = vec![0; n]; let mut ord = (0..n).collect::<Vec<_>>(); ord.sort_by_key(|v| a[*v]); for x in ord.into_iter().rev() { let a = a[x]; let ans = &mut ans[x]; let (_, k) = h.pop().unwrap(); if rem[k] < a { return None; } *ans = k; rem[k] -= a; h.push((rem[k], k)); } Some(ans) }