pub struct SparseGraph<D> {
vsize: usize,
start: Vec<usize>,
neighbors: Vec<Neighbor<usize, usize>>,
pub edges: Vec<(usize, usize)>,
_marker: PhantomData<fn() -> D>,
}Expand description
Static Sparse Graph represented as Compressed Sparse Row.
Fields§
§vsize: usize§start: Vec<usize>§neighbors: Vec<Neighbor<usize, usize>>§edges: Vec<(usize, usize)>§_marker: PhantomData<fn() -> D>Implementations§
Source§impl<D> SparseGraph<D>
impl<D> SparseGraph<D>
Sourcepub fn vertices_size(&self) -> usize
pub fn vertices_size(&self) -> usize
Return the number of vertices.
Examples found in repository?
More examples
crates/competitive/src/tree/depth.rs (line 13)
12 pub fn tree_depth(&self, root: usize) -> Vec<u64> {
13 let mut depth = vec![0; self.vertices_size()];
14 self.depth_dfs(root, self.vertices_size(), 0, &mut depth);
15 depth
16 }
17}
18
19#[codesnip::entry("weighted_tree_depth", include("algebra", "SparseGraph"))]
20impl UndirectedSparseGraph {
21 fn weighted_depth_dfs<M, F>(
22 &self,
23 u: usize,
24 p: usize,
25 d: M::T,
26 depth: &mut Vec<M::T>,
27 weight: &F,
28 ) where
29 M: Monoid,
30 F: Fn(usize) -> M::T,
31 {
32 for a in self.neighbors(u).filter(|a| a.to != p) {
33 let nd = M::operate(&d, &weight(a.label));
34 self.weighted_depth_dfs::<M, _>(a.to, u, nd, depth, weight);
35 }
36 depth[u] = d;
37 }
38 pub fn weighted_tree_depth<M: Monoid, F: Fn(usize) -> M::T>(
39 &self,
40 root: usize,
41 weight: F,
42 ) -> Vec<M::T> {
43 let mut depth = vec![M::unit(); self.vertices_size()];
44 self.weighted_depth_dfs::<M, _>(root, usize::MAX, M::unit(), &mut depth, &weight);
45 depth
46 }
47}
48
49#[codesnip::entry("tree_size", include("SparseGraph"))]
50impl UndirectedSparseGraph {
51 fn size_dfs(&self, u: usize, p: usize, size: &mut Vec<u64>) {
52 size[u] = 1;
53 for a in self.neighbors(u).filter(|a| a.to != p) {
54 self.size_dfs(a.to, u, size);
55 size[u] += size[a.to];
56 }
57 }
58 pub fn tree_size(&self, root: usize) -> Vec<u64> {
59 let mut size = vec![0; self.vertices_size()];
60 self.size_dfs(root, usize::MAX, &mut size);
61 size
62 }crates/competitive/src/tree/euler_tour.rs (line 68)
67 pub fn new(tree: &'a UndirectedSparseGraph, root: usize) -> Self {
68 let n = tree.vertices_size();
69 Self {
70 tree,
71 root,
72 vidx: vec![[0usize; 2]; n],
73 eidx: vec![[0usize; 2]; n - 1],
74 pos: 0,
75 _marker: PhantomData,
76 }
77 }
78
79 pub fn build_with_trace(mut self, mut trace: impl FnMut(usize)) -> EulerTour<K> {
80 self.dfs(self.root, !0, &mut trace);
81 EulerTour {
82 root: self.root,
83 vidx: self.vidx,
84 eidx: self.eidx,
85 size: self.pos,
86 _marker: PhantomData,
87 }
88 }
89
90 pub fn build(self) -> EulerTour<K> {
91 self.build_with_trace(|_u| {})
92 }
93
94 fn dfs(&mut self, u: usize, parent: usize, trace: &mut impl FnMut(usize)) {
95 self.vidx[u][0] = self.pos;
96 trace(u);
97 self.pos += 1;
98 for a in self.tree.neighbors(u) {
99 if a.to != parent {
100 self.eidx[a.label][0] = self.pos;
101 self.dfs(a.to, u, trace);
102 self.eidx[a.label][1] = self.pos;
103 if K::USE_VISIT {
104 trace(u);
105 self.pos += 1;
106 }
107 }
108 }
109 self.vidx[u][1] = self.pos;
110 if K::USE_LAST {
111 trace(u);
112 self.pos += 1;
113 }
114 }
115}
116
117impl EulerTourBuilder<'_, marker::First> {
118 pub fn build_with_rearrange<T>(self, s: &[T]) -> (EulerTour<marker::First>, Vec<T>)
119 where
120 T: Clone,
121 {
122 assert_eq!(s.len(), self.tree.vertices_size());
123 let mut trace = Vec::with_capacity(marker::First::size(s.len()));
124 let tour = self.build_with_trace(|u| {
125 trace.push(s[u].clone());
126 });
127 (tour, trace)
128 }
129}
130
131impl EulerTourBuilder<'_, marker::FirstLast> {
132 pub fn build_with_rearrange<T>(
133 self,
134 s: &[T],
135 mut inverse: impl FnMut(T) -> T,
136 ) -> (EulerTour<marker::FirstLast>, Vec<T>)
137 where
138 T: Clone,
139 {
140 assert_eq!(s.len(), self.tree.vertices_size());
141 let mut visited = vec![false; s.len()];
142 let mut trace = Vec::with_capacity(marker::FirstLast::size(s.len()));
143 let tour = self.build_with_trace(|u| {
144 if !visited[u] {
145 trace.push(s[u].clone());
146 visited[u] = true;
147 } else {
148 trace.push(inverse(s[u].clone()));
149 }
150 });
151 (tour, trace)
152 }
153}
154
155impl EulerTourBuilder<'_, marker::Visit> {
156 pub fn build_with_rearrange<T>(self, s: &[T]) -> (EulerTour<marker::Visit>, Vec<T>)
157 where
158 T: Clone,
159 {
160 assert_eq!(s.len(), self.tree.vertices_size());
161 let mut trace = Vec::with_capacity(marker::Visit::size(s.len()));
162 let tour = self.build_with_trace(|u| {
163 trace.push(s[u].clone());
164 });
165 (tour, trace)
166 }crates/competitive/src/tree/rerooting.rs (line 41)
37 fn build<I>(graph: &'a UndirectedSparseGraph, rooting: F, inverse: Option<I>) -> Self
38 where
39 I: Fn(&M::T, &M::T) -> M::T,
40 {
41 let dp = vec![M::unit(); graph.vertices_size()];
42 let ep = vec![M::unit(); graph.vertices_size() * 2];
43 let mut self_ = Self {
44 graph,
45 dp,
46 ep,
47 rooting,
48 };
49 self_.rerooting(inverse);
50 self_
51 }crates/competitive/src/graph/low_link.rs (line 14)
11 pub fn new(graph: &'a UndirectedSparseGraph) -> Self {
12 let mut self_ = Self {
13 graph,
14 low: vec![0; graph.vertices_size()],
15 ord: vec![usize::MAX; graph.vertices_size()],
16 articulation: vec![],
17 bridge: vec![],
18 };
19 for u in graph.vertices() {
20 if self_.ord[u] == usize::MAX {
21 self_.dfs(u, !0, &mut 0);
22 }
23 }
24 self_
25 }crates/competitive/src/tree/tree_order.rs (line 10)
9 pub fn tree_order(&self, root: usize) -> (Vec<usize>, Vec<usize>) {
10 let n = self.vertices_size();
11 let mut order = Vec::with_capacity(n);
12 let mut parents = vec![!0usize; n];
13 let mut stack = Vec::with_capacity(n);
14 stack.push(root);
15 while let Some(u) = stack.pop() {
16 order.push(u);
17 for a in self.neighbors(u).rev() {
18 if a.to != parents[u] {
19 parents[a.to] = u;
20 stack.push(a.to);
21 }
22 }
23 }
24 (order, parents)
25 }Additional examples can be found in:
- crates/competitive/src/tree/tree_centroid.rs
- crates/competitive/src/tree/centroid_decomposition.rs
- crates/competitive/src/graph/maximum_flow.rs
- crates/competitive/src/graph/minimum_cost_flow.rs
- crates/competitive/src/tree/distance_frequencies.rs
- crates/competitive/src/tree/tree_center.rs
- crates/competitive/src/tree/level_ancestor.rs
- crates/competitive/src/graph/strongly_connected_component.rs
- crates/competitive/src/tree/heavy_light_decomposition.rs
- crates/competitive/src/tree/static_top_tree.rs
Sourcepub fn edges_size(&self) -> usize
pub fn edges_size(&self) -> usize
Return the number of edges.
Examples found in repository?
More examples
crates/competitive/src/tree/static_top_tree.rs (line 160)
156 pub fn new(root: usize, graph: &UndirectedSparseGraph) -> Self {
157 let n = graph.vertices_size();
158 assert!(n > 0);
159 assert!(root < n);
160 assert_eq!(graph.edges_size() + 1, n);
161
162 let RootedInfo {
163 order,
164 children_start,
165 children,
166 edge_child,
167 parent_edge,
168 } = rooted_children(graph, root);
169 let mut this = Self {
170 root,
171 n,
172 edge_child,
173 parent_edge,
174 compressed: Vec::with_capacity(n.saturating_sub(1)),
175 raked: Vec::with_capacity(n.saturating_sub(1)),
176 vertex_links: vec![
177 VertexLinks {
178 heavy_parent: usize::MAX,
179 compress_parent: usize::MAX,
180 rake_parent: usize::MAX,
181 };
182 n
183 ],
184 compress_roots: vec![None; n],
185 rake_roots: vec![None; n],
186 };
187
188 let mut heavy_child = vec![usize::MAX; n];
189 let mut mask = vec![1u64; n];
190 let mut buckets: [Vec<Node>; 64] = std::array::from_fn(|_| Vec::new());
191
192 for &u in order.iter().rev() {
193 let children = &children[children_start[u]..children_start[u + 1]];
194 let mut sum_rake = 0u64;
195 for &v in children {
196 sum_rake += bit_ceil(mask[v]) << 1;
197 }
198 mask[u] = bit_ceil(sum_rake);
199 for &v in children {
200 let child = bit_ceil(mask[v]) << 1;
201 let depth = bit_ceil(sum_rake - child).trailing_zeros() as usize;
202 let step = 1u64 << depth;
203 let cand = ((mask[v] + step - 1) >> depth << depth) + step;
204 if cand <= mask[u] {
205 mask[u] = cand;
206 heavy_child[u] = v;
207 }
208 }
209
210 let mut has = 0u64;
211 let mut num_light = 0usize;
212 for &v in children {
213 if v == heavy_child[u] {
214 continue;
215 }
216 num_light += 1;
217 let child = bit_ceil(mask[v]) << 1;
218 let depth = bit_ceil(sum_rake - child).trailing_zeros() as usize;
219 this.build_compress(v, &heavy_child, &mask);
220 buckets[depth].push(Node {
221 depth,
222 slot: Slot::RakeLeaf(v),
223 });
224 has |= 1u64 << depth;
225 }
226 if num_light == 0 {
227 continue;
228 }
229
230 while num_light > 1 {
231 let left = pop_bucket(&mut buckets, &mut has);
232 let right = pop_bucket(&mut buckets, &mut has);
233 let node = this.merge_rake(left, right);
234 let depth = node.depth;
235 buckets[depth].push(node);
236 has |= 1u64 << depth;
237 num_light -= 1;
238 }
239
240 let root = pop_bucket(&mut buckets, &mut has);
241 this.rake_roots[u] = Some(root.slot);
242 for &v0 in children {
243 if v0 == heavy_child[u] {
244 continue;
245 }
246 let rake_parent = this.vertex_links[v0].rake_parent;
247 let mut v = v0;
248 while v != usize::MAX {
249 this.vertex_links[v].heavy_parent = u;
250 this.vertex_links[v].rake_parent = rake_parent;
251 v = heavy_child[v];
252 }
253 }
254 }
255
256 this.build_compress(root, &heavy_child, &mask);
257 this
258 }
259
260 pub fn vertices_size(&self) -> usize {
261 self.n
262 }
263
264 pub fn edges_size(&self) -> usize {
265 self.edge_child.len()
266 }
267
268 pub fn dp<C>(
269 &self,
270 vertices: Vec<<C as Cluster>::Vertex>,
271 edges: Vec<<C as Cluster>::Edge>,
272 ) -> StaticTopTreeDp<'_, C>
273 where
274 C: Cluster,
275 {
276 StaticTopTreeDp::new(self, vertices, edges)
277 }
278
279 pub fn fold_all<C>(
280 &self,
281 vertices: &[<C as Cluster>::Vertex],
282 edges: &[<C as Cluster>::Edge],
283 ) -> <C as Cluster>::Point
284 where
285 C: Cluster,
286 {
287 assert_eq!(vertices.len(), self.vertices_size());
288 assert_eq!(edges.len(), self.edges_size());
289 let path = self.fold_compress::<C>(
290 vertices,
291 edges,
292 self.compress_roots[self.root].expect("root compress tree must exist"),
293 );
294 C::add_edge(&path)
295 }
296
297 fn build_compress(&mut self, mut vertex: usize, heavy_child: &[usize], mask: &[u64]) -> Node {
298 let start = vertex;
299 let mut stack = Vec::new();
300 while vertex != usize::MAX {
301 stack.push(Node {
302 depth: bit_ceil(mask[vertex]).trailing_zeros() as usize,
303 slot: Slot::CompressLeaf(vertex),
304 });
305 loop {
306 let len = stack.len();
307 if len >= 3
308 && (stack[len - 3].depth == stack[len - 2].depth
309 || stack[len - 3].depth <= stack[len - 1].depth)
310 {
311 let tail = stack.pop().unwrap();
312 let right = stack.pop().unwrap();
313 let left = stack.pop().unwrap();
314 let node = self.merge_compress(left, right);
315 stack.push(node);
316 stack.push(tail);
317 } else if len >= 2 && stack[len - 2].depth <= stack[len - 1].depth {
318 let right = stack.pop().unwrap();
319 let left = stack.pop().unwrap();
320 stack.push(self.merge_compress(left, right));
321 } else {
322 break;
323 }
324 }
325 vertex = heavy_child[vertex];
326 }
327 while stack.len() > 1 {
328 let right = stack.pop().unwrap();
329 let left = stack.pop().unwrap();
330 stack.push(self.merge_compress(left, right));
331 }
332 let root = stack.pop().unwrap();
333 self.compress_roots[start] = Some(root.slot);
334 root
335 }
336
337 fn merge_compress(&mut self, left: Node, right: Node) -> Node {
338 let id = self.compressed.len();
339 self.set_parent(left.slot, id << 1);
340 self.set_parent(right.slot, id << 1 | 1);
341 self.compressed.push(InnerNode {
342 left: left.slot,
343 right: right.slot,
344 parent: usize::MAX,
345 });
346 Node {
347 depth: left.depth.max(right.depth) + 1,
348 slot: Slot::CompressInner(id),
349 }
350 }
351
352 fn merge_rake(&mut self, left: Node, right: Node) -> Node {
353 let id = self.raked.len();
354 self.set_parent(left.slot, id << 1);
355 self.set_parent(right.slot, id << 1 | 1);
356 self.raked.push(InnerNode {
357 left: left.slot,
358 right: right.slot,
359 parent: usize::MAX,
360 });
361 Node {
362 depth: left.depth.max(right.depth) + 1,
363 slot: Slot::RakeInner(id),
364 }
365 }
366
367 fn set_parent(&mut self, slot: Slot, parent: usize) {
368 match slot {
369 Slot::CompressLeaf(v) => self.vertex_links[v].compress_parent = parent,
370 Slot::CompressInner(i) => self.compressed[i].parent = parent,
371 Slot::RakeLeaf(v) => self.vertex_links[v].rake_parent = parent,
372 Slot::RakeInner(i) => self.raked[i].parent = parent,
373 }
374 }
375
376 fn init_compress<C>(
377 &self,
378 data: &mut StaticTopTreeDataBuilder<C>,
379 vertices: &[<C as Cluster>::Vertex],
380 edges: &[<C as Cluster>::Edge],
381 slot: Slot,
382 ) -> <C as Cluster>::Path
383 where
384 C: Cluster,
385 {
386 match slot {
387 Slot::CompressLeaf(vertex) => {
388 let point = self.init_point(data, vertices, edges, vertex);
389 C::add_vertex(
390 &point,
391 &vertices[vertex],
392 self.parent_edge_ref(edges, vertex),
393 )
394 }
395 Slot::CompressInner(id) => {
396 let node = &self.compressed[id];
397 let left = self.init_compress(data, vertices, edges, node.left);
398 let right = self.init_compress(data, vertices, edges, node.right);
399 data.compressed[id].write(InnerValue {
400 parent: node.parent,
401 left: left.clone(),
402 right: right.clone(),
403 });
404 C::compress(&left, &right)
405 }
406 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
407 }
408 }
409
410 fn fold_compress<C>(
411 &self,
412 vertices: &[<C as Cluster>::Vertex],
413 edges: &[<C as Cluster>::Edge],
414 slot: Slot,
415 ) -> <C as Cluster>::Path
416 where
417 C: Cluster,
418 {
419 match slot {
420 Slot::CompressLeaf(vertex) => {
421 let point = self.fold_point::<C>(vertices, edges, vertex);
422 C::add_vertex(
423 &point,
424 &vertices[vertex],
425 self.parent_edge_ref(edges, vertex),
426 )
427 }
428 Slot::CompressInner(id) => {
429 let node = &self.compressed[id];
430 let left = self.fold_compress::<C>(vertices, edges, node.left);
431 let right = self.fold_compress::<C>(vertices, edges, node.right);
432 C::compress(&left, &right)
433 }
434 Slot::RakeLeaf(_) | Slot::RakeInner(_) => unreachable!(),
435 }
436 }
437
438 fn init_point<C>(
439 &self,
440 data: &mut StaticTopTreeDataBuilder<C>,
441 vertices: &[<C as Cluster>::Vertex],
442 edges: &[<C as Cluster>::Edge],
443 vertex: usize,
444 ) -> <C as Cluster>::Point
445 where
446 C: Cluster,
447 {
448 let point = if let Some(slot) = self.rake_roots[vertex] {
449 self.init_rake(data, vertices, edges, slot)
450 } else {
451 C::unit_point()
452 };
453 data.light_points[vertex] = point.clone();
454 point
455 }
456
457 fn fold_point<C>(
458 &self,
459 vertices: &[<C as Cluster>::Vertex],
460 edges: &[<C as Cluster>::Edge],
461 vertex: usize,
462 ) -> <C as Cluster>::Point
463 where
464 C: Cluster,
465 {
466 if let Some(slot) = self.rake_roots[vertex] {
467 self.fold_rake::<C>(vertices, edges, slot)
468 } else {
469 C::unit_point()
470 }
471 }
472
473 fn init_rake<C>(
474 &self,
475 data: &mut StaticTopTreeDataBuilder<C>,
476 vertices: &[<C as Cluster>::Vertex],
477 edges: &[<C as Cluster>::Edge],
478 slot: Slot,
479 ) -> <C as Cluster>::Point
480 where
481 C: Cluster,
482 {
483 match slot {
484 Slot::RakeLeaf(vertex) => {
485 let path = self.init_compress(
486 data,
487 vertices,
488 edges,
489 self.compress_roots[vertex].expect("light child path must exist"),
490 );
491 C::add_edge(&path)
492 }
493 Slot::RakeInner(id) => {
494 let node = &self.raked[id];
495 let left = self.init_rake(data, vertices, edges, node.left);
496 let right = self.init_rake(data, vertices, edges, node.right);
497 data.raked[id].write(InnerValue {
498 parent: node.parent,
499 left: left.clone(),
500 right: right.clone(),
501 });
502 C::rake(&left, &right)
503 }
504 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
505 }
506 }
507
508 fn fold_rake<C>(
509 &self,
510 vertices: &[<C as Cluster>::Vertex],
511 edges: &[<C as Cluster>::Edge],
512 slot: Slot,
513 ) -> <C as Cluster>::Point
514 where
515 C: Cluster,
516 {
517 match slot {
518 Slot::RakeLeaf(vertex) => {
519 let path = self.fold_compress::<C>(
520 vertices,
521 edges,
522 self.compress_roots[vertex].expect("light child path must exist"),
523 );
524 C::add_edge(&path)
525 }
526 Slot::RakeInner(id) => {
527 let node = &self.raked[id];
528 let left = self.fold_rake::<C>(vertices, edges, node.left);
529 let right = self.fold_rake::<C>(vertices, edges, node.right);
530 C::rake(&left, &right)
531 }
532 Slot::CompressLeaf(_) | Slot::CompressInner(_) => unreachable!(),
533 }
534 }
535
536 fn parent_edge_ref<'a, T>(&self, edges: &'a [T], vertex: usize) -> Option<&'a T> {
537 let edge = self.parent_edge[vertex];
538 if edge == usize::MAX {
539 None
540 } else {
541 Some(&edges[edge])
542 }
543 }
544}
545
546impl<'a, C> StaticTopTreeDp<'a, C>
547where
548 C: Cluster,
549{
550 pub fn new(
551 tree: &'a StaticTopTree,
552 vertices: Vec<<C as Cluster>::Vertex>,
553 edges: Vec<<C as Cluster>::Edge>,
554 ) -> Self {
555 assert_eq!(vertices.len(), tree.vertices_size());
556 assert_eq!(edges.len(), tree.edges_size());
557
558 let mut data: StaticTopTreeDataBuilder<C> = StaticTopTreeDataBuilder::new(tree);
559 let path = tree.init_compress(
560 &mut data,
561 &vertices,
562 &edges,
563 tree.compress_roots[tree.root].expect("root compress tree must exist"),
564 );
565 let all_point = C::add_edge(&path);
566 Self {
567 tree,
568 vertices,
569 edges,
570 compressed: unsafe { assume_init_vec(data.compressed) },
571 raked: unsafe { assume_init_vec(data.raked) },
572 light_points: data.light_points,
573 all_point,
574 }
575 }
576
577 pub fn get_vertex(&self, vertex: usize) -> &<C as Cluster>::Vertex {
578 &self.vertices[vertex]
579 }
580
581 pub fn apply_vertex<F>(&mut self, vertex: usize, f: F)
582 where
583 F: FnOnce(&mut <C as Cluster>::Vertex),
584 {
585 assert!(vertex < self.vertices.len());
586 f(&mut self.vertices[vertex]);
587 self.update_from_vertex(vertex);
588 }
589
590 pub fn set_vertex(&mut self, vertex: usize, value: <C as Cluster>::Vertex) {
591 self.apply_vertex(vertex, |x| *x = value);
592 }
593
594 pub fn get_edge(&self, edge: usize) -> &<C as Cluster>::Edge {
595 &self.edges[edge]
596 }
597
598 pub fn apply_edge<F>(&mut self, edge: usize, f: F)
599 where
600 F: FnOnce(&mut <C as Cluster>::Edge),
601 {
602 assert!(edge < self.edges.len());
603 f(&mut self.edges[edge]);
604 self.update_from_vertex(self.tree.edge_child[edge]);
605 }
606
607 pub fn set_edge(&mut self, edge: usize, value: <C as Cluster>::Edge) {
608 self.apply_edge(edge, |x| *x = value);
609 }
610
611 pub fn fold_all(&self) -> &<C as Cluster>::Point {
612 &self.all_point
613 }
614
615 #[inline(always)]
616 pub fn fold_path(&self, mut vertex: usize) -> <C as Cluster>::Path {
617 assert!(vertex < self.tree.n);
618 let mut path = C::unit_path();
619 let mut point = self.light_points[vertex].clone();
620 loop {
621 let links = self.tree.vertex_links[vertex];
622 let mut left = C::unit_path();
623 let mut right = C::unit_path();
624 let mut compress_parent = links.compress_parent;
625 while compress_parent != usize::MAX {
626 let inner = &self.compressed[compress_parent / 2];
627 if compress_parent & 1 == 0 {
628 right = C::compress(&right, &inner.right);
629 } else {
630 left = C::compress(&inner.left, &left);
631 }
632 compress_parent = inner.parent;
633 }
634 let right_point = C::add_edge(&right);
635 point = C::rake(&point, &right_point);
636 let mid = C::add_vertex(
637 &point,
638 &self.vertices[vertex],
639 self.tree.parent_edge_ref(&self.edges, vertex),
640 );
641 let mid = C::compress(&mid, &path);
642 path = C::compress(&left, &mid);
643 if links.heavy_parent == usize::MAX {
644 return path;
645 }
646
647 point = C::unit_point();
648 let mut rake_parent = links.rake_parent;
649 while rake_parent != usize::MAX {
650 let inner = &self.raked[rake_parent / 2];
651 if rake_parent & 1 == 0 {
652 point = C::rake(&point, &inner.right);
653 } else {
654 point = C::rake(&inner.left, &point);
655 }
656 rake_parent = inner.parent;
657 }
658 vertex = links.heavy_parent;
659 }
660 }
661
662 fn update_from_vertex(&mut self, mut vertex: usize) {
663 assert!(vertex < self.tree.n);
664 while vertex != usize::MAX {
665 let links = self.tree.vertex_links[vertex];
666 let base = C::add_vertex(
667 &self.light_points[vertex],
668 &self.vertices[vertex],
669 self.tree.parent_edge_ref(&self.edges, vertex),
670 );
671 let path = self.update_compress(links.compress_parent, base);
672 let point = C::add_edge(&path);
673 let point = self.update_rake(links.rake_parent, point);
674 if links.heavy_parent == usize::MAX {
675 self.all_point = point;
676 } else {
677 self.light_points[links.heavy_parent] = point;
678 }
679 vertex = links.heavy_parent;
680 }
681 }
682
683 fn update_compress(
684 &mut self,
685 mut id: usize,
686 mut path: <C as Cluster>::Path,
687 ) -> <C as Cluster>::Path {
688 while id != usize::MAX {
689 let inner = &mut self.compressed[id / 2];
690 if id & 1 == 0 {
691 inner.left = path;
692 } else {
693 inner.right = path;
694 }
695 path = C::compress(&inner.left, &inner.right);
696 id = inner.parent;
697 }
698 path
699 }
700
701 fn update_rake(
702 &mut self,
703 mut id: usize,
704 mut point: <C as Cluster>::Point,
705 ) -> <C as Cluster>::Point {
706 while id != usize::MAX {
707 let inner = &mut self.raked[id / 2];
708 if id & 1 == 0 {
709 inner.left = point;
710 } else {
711 inner.right = point;
712 }
713 point = C::rake(&inner.left, &inner.right);
714 id = inner.parent;
715 }
716 point
717 }
718}
719
720struct StaticTopTreeDataBuilder<C>
721where
722 C: Cluster,
723{
724 compressed: Vec<MaybeUninit<InnerValue<<C as Cluster>::Path>>>,
725 raked: Vec<MaybeUninit<InnerValue<<C as Cluster>::Point>>>,
726 light_points: Vec<<C as Cluster>::Point>,
727}
728
729impl<C> StaticTopTreeDataBuilder<C>
730where
731 C: Cluster,
732{
733 fn new(tree: &StaticTopTree) -> Self {
734 let mut compressed = Vec::with_capacity(tree.compressed.len());
735 compressed.resize_with(tree.compressed.len(), MaybeUninit::uninit);
736 let mut raked = Vec::with_capacity(tree.raked.len());
737 raked.resize_with(tree.raked.len(), MaybeUninit::uninit);
738 Self {
739 compressed,
740 raked,
741 light_points: vec![C::unit_point(); tree.n],
742 }
743 }
744}
745
746unsafe fn assume_init_vec<T>(mut vec: Vec<MaybeUninit<T>>) -> Vec<T> {
747 let len = vec.len();
748 let cap = vec.capacity();
749 let ptr = vec.as_mut_ptr() as *mut T;
750 std::mem::forget(vec);
751 unsafe { Vec::from_raw_parts(ptr, len, cap) }
752}
753
754fn bit_ceil(x: u64) -> u64 {
755 if x <= 1 { 1 } else { x.next_power_of_two() }
756}
757
758fn rooted_children(graph: &UndirectedSparseGraph, root: usize) -> RootedInfo {
759 let n = graph.vertices_size();
760 let mut order = Vec::with_capacity(n);
761 let mut parent = vec![usize::MAX; n];
762 let mut parent_edge = vec![usize::MAX; n];
763 let mut edge_child = vec![0; graph.edges_size()];
764 order.push(root);
765 parent[root] = usize::MAX;
766 for i in 0..n {
767 let u = order[i];
768 for a in graph.neighbors(u) {
769 if a.to == parent[u] {
770 continue;
771 }
772 parent[a.to] = u;
773 parent_edge[a.to] = a.label;
774 edge_child[a.label] = a.to;
775 order.push(a.to);
776 }
777 }
778 let mut children_start = vec![0usize; n + 1];
779 for &v in order.iter().skip(1) {
780 children_start[parent[v] + 1] += 1;
781 }
782 for i in 1..=n {
783 children_start[i] += children_start[i - 1];
784 }
785 let mut children = vec![0; n.saturating_sub(1)];
786 let mut child_pos = children_start.clone();
787 for &v in order.iter().skip(1) {
788 let pos = child_pos[parent[v]];
789 children[pos] = v;
790 child_pos[parent[v]] += 1;
791 }
792 RootedInfo {
793 order,
794 children_start,
795 children,
796 edge_child,
797 parent_edge,
798 }
799}Sourcepub fn vertices(&self) -> Range<usize> ⓘ
pub fn vertices(&self) -> Range<usize> ⓘ
Return an iterator over graph vertices.
Examples found in repository?
crates/aizu_online_judge/src/grl/grl_1_a.rs (line 12)
8pub fn grl_1_a(reader: impl Read, writer: impl Write) {
9 prepare_io!(reader, writer);
10 sc!(vs, es, r, (graph, d): @DirectedGraphScanner::<usize, u64>::new(vs, es));
11 let cost = graph.standard_sp_additive().dijkstra([r], |eid| d[eid]);
12 for u in graph.vertices() {
13 if cost[u].is_maximum() {
14 pp!("INF");
15 } else {
16 pp!(cost[u]);
17 }
18 }
19}
20
21#[verify::aizu_online_judge("GRL_1_A")]
22pub fn grl_1_a_option(reader: impl Read, writer: impl Write) {
23 prepare_io!(reader, writer);
24 sc!(vs, es, r, (graph, d): @DirectedGraphScanner::<usize, u64>::new(vs, es));
25 let cost = graph.option_sp_additive().dijkstra([r], |eid| Some(d[eid]));
26 for u in graph.vertices() {
27 match cost[u] {
28 Some(d) => pp!(d),
29 None => pp!("INF"),
30 };
31 }
32}More examples
crates/competitive/src/graph/low_link.rs (line 19)
11 pub fn new(graph: &'a UndirectedSparseGraph) -> Self {
12 let mut self_ = Self {
13 graph,
14 low: vec![0; graph.vertices_size()],
15 ord: vec![usize::MAX; graph.vertices_size()],
16 articulation: vec![],
17 bridge: vec![],
18 };
19 for u in graph.vertices() {
20 if self_.ord[u] == usize::MAX {
21 self_.dfs(u, !0, &mut 0);
22 }
23 }
24 self_
25 }crates/aizu_online_judge/src/grl/grl_1_b.rs (line 12)
5pub fn grl_1_b(reader: impl Read, writer: impl Write) {
6 prepare_io!(reader, writer);
7 sc!(vs, es, r, (graph, d): @DirectedGraphScanner::<usize, i64>::new(vs, es));
8 let cost = graph
9 .option_sp_additive()
10 .bellman_ford([r], |eid| Some(d[eid]), true);
11 if let Some(cost) = cost {
12 for u in graph.vertices() {
13 match cost[u] {
14 Some(d) => pp!(d),
15 None => pp!("INF"),
16 };
17 }
18 } else {
19 pp!("NEGATIVE CYCLE");
20 }
21}crates/competitive/src/graph/graphvis.rs (line 14)
5 pub fn to_graphvis<N, NA, E, EA>(&self, node_attr: N, edge_attr: E) -> String
6 where
7 N: Fn(usize) -> NA,
8 E: Fn(usize) -> EA,
9 NA: Display,
10 EA: Display,
11 {
12 let mut s = String::new();
13 s.push_str("digraph G {\n graph [ splines=false, layout=neato ];\n");
14 for u in self.vertices() {
15 writeln!(s, " {} [{}];", u, node_attr(u)).ok();
16 }
17 for u in self.vertices() {
18 for a in self.neighbors(u) {
19 writeln!(s, " {} -> {} [{}];", u, a.to, edge_attr(a.label)).ok();
20 }
21 }
22 s.push('}');
23 s
24 }
25}
26
27impl UndirectedSparseGraph {
28 pub fn to_graphvis<N, NA, E, EA>(&self, node_attr: N, edge_attr: E) -> String
29 where
30 N: Fn(usize) -> NA,
31 E: Fn(usize) -> EA,
32 NA: Display,
33 EA: Display,
34 {
35 let mut s = String::new();
36 s.push_str("graph G {\n graph [ splines=false, layout=neato ];\n");
37 for u in self.vertices() {
38 writeln!(s, " {} [{}];", u, node_attr(u)).ok();
39 }
40 for (i, (u, v)) in self.edges.iter().cloned().enumerate() {
41 writeln!(s, " {} -- {} [{}];", u, v, edge_attr(i)).ok();
42 }
43 s.push('}');
44 s
45 }
46}
47
48impl BidirectionalSparseGraph {
49 pub fn to_graphvis<N, NA, E, EA>(&self, node_attr: N, edge_attr: E) -> String
50 where
51 N: Fn(usize) -> NA,
52 E: Fn(usize) -> EA,
53 NA: Display,
54 EA: Display,
55 {
56 let mut s = String::new();
57 s.push_str("digraph G {\n graph [ splines=false, layout=neato ];\n");
58 for u in self.vertices() {
59 writeln!(s, " {} [{}];", u, node_attr(u)).ok();
60 }
61 for u in self.vertices() {
62 for a in self.neighbors(u) {
63 writeln!(s, " {} -> {} [{}];", u, a.to, edge_attr(a.label)).ok();
64 }
65 }
66 s.push('}');
67 s
68 }crates/aizu_online_judge/src/grl/grl_1_c.rs (line 14)
8pub fn grl_1_c(reader: impl Read, writer: impl Write) {
9 prepare_io!(reader, writer);
10 sc!(vs, es, (graph, d): @DirectedGraphScanner::<usize, i64>::new(vs, es));
11 let cost = graph
12 .option_sp_additive()
13 .warshall_floyd_ap(|eid| Some(Saturating(d[eid])));
14 if graph.vertices().any(|u| cost[u][u].unwrap().0 < 0) {
15 pp!("NEGATIVE CYCLE");
16 } else {
17 for u in graph.vertices() {
18 for v in graph.vertices() {
19 match cost[u][v] {
20 Some(d) => pp!(d.0, !),
21 None => pp!("INF", !),
22 };
23 pp!(if v + 1 == vs { '\n' } else { ' ' }, !);
24 }
25 }
26 }
27}crates/competitive/src/graph/minimum_cost_flow.rs (line 85)
79 fn bellman_ford(&mut self, s: usize) {
80 self.potential.clear();
81 self.potential.resize(self.graph.vertices_size(), i64::MAX);
82 self.potential[s] = 0;
83 for _ in 1..self.graph.vertices_size() {
84 let mut end = true;
85 for u in self.graph.vertices() {
86 if self.potential[u] == i64::MAX {
87 continue;
88 }
89 for a in self.graph.neighbors(u) {
90 if self.capacities[a.label] == 0 {
91 continue;
92 }
93 let ncost = self.potential[u].saturating_add(self.costs[a.label]);
94 if self.potential[a.to] > ncost {
95 self.potential[a.to] = ncost;
96 end = false;
97 }
98 }
99 }
100 if end {
101 break;
102 }
103 }
104 }Additional examples can be found in:
pub fn builder<T>(vsize: usize) -> SparseGraphBuilder<T, D>
pub fn builder_with_esize<T>( vsize: usize, esize: usize, ) -> SparseGraphBuilder<T, D>
Source§impl<D> SparseGraph<D>where
D: SparseGraphConstruction,
impl<D> SparseGraph<D>where
D: SparseGraphConstruction,
Sourcepub fn from_edges(vsize: usize, edges: Vec<(usize, usize)>) -> Self
pub fn from_edges(vsize: usize, edges: Vec<(usize, usize)>) -> Self
Construct graph from edges.
Examples found in repository?
More examples
crates/competitive/src/tree/generator.rs (line 15)
7 fn rand(&self, rng: &mut Xorshift) -> UndirectedSparseGraph {
8 let n = rng.random(&self.0);
9 let edges = from_prufer_sequence(
10 n,
11 &rng.random_iter(0..n)
12 .take(n.saturating_sub(2))
13 .collect::<Vec<usize>>(),
14 );
15 UndirectedSparseGraph::from_edges(n, edges)
16 }
17}
18
19pub struct PathTree<T>(pub T);
20
21impl<T: RandomSpec<usize>> RandomSpec<UndirectedSparseGraph> for PathTree<T> {
22 fn rand(&self, rng: &mut Xorshift) -> UndirectedSparseGraph {
23 let n = rng.random(&self.0);
24 let edges = (1..n).map(|u| (u - 1, u)).collect();
25 UndirectedSparseGraph::from_edges(n, edges)
26 }
27}
28
29pub struct StarTree<T>(pub T);
30
31impl<T: RandomSpec<usize>> RandomSpec<UndirectedSparseGraph> for StarTree<T> {
32 fn rand(&self, rng: &mut Xorshift) -> UndirectedSparseGraph {
33 let n = rng.random(&self.0);
34 let edges = (1..n).map(|u| (0, u)).collect();
35 UndirectedSparseGraph::from_edges(n, edges)
36 }
37}
38
39pub struct MixedTree<T>(pub T);
40
41impl<T: RandomSpec<usize>> RandomSpec<UndirectedSparseGraph> for MixedTree<T> {
42 fn rand(&self, rng: &mut Xorshift) -> UndirectedSparseGraph {
43 fn rand_inner(n: usize, rng: &mut Xorshift) -> Vec<(usize, usize)> {
44 let mut edges = Vec::with_capacity(n.saturating_sub(1));
45 if n >= 2 {
46 let k = rng.random(1..n);
47 for n in [k, n - k].iter().cloned() {
48 let ty = rng.rand(6);
49 edges.extend(match ty {
50 0 => from_prufer_sequence(
51 n,
52 &rng.random_iter(0..n)
53 .take(n.saturating_sub(2))
54 .collect::<Vec<usize>>(),
55 ),
56 1 => (1..n).map(|u| (u - 1, u)).collect(),
57 2 => (1..n).map(|u| (0, u)).collect(),
58 _ => rand_inner(n, rng),
59 });
60 }
61 for (u, v) in edges[k - 1..].iter_mut() {
62 *u += k;
63 *v += k;
64 }
65 edges.push((rng.random(0..k), rng.random(k..n)));
66 }
67 edges
68 }
69 let n = rng.random(&self.0);
70 let edges = rand_inner(n, rng);
71 UndirectedSparseGraph::from_edges(n, edges)
72 }Additional examples can be found in:
- crates/aizu_online_judge/src/grl/grl_5_c.rs
- crates/competitive/src/graph/two_satisfiability.rs
- crates/competitive/src/graph/strongly_connected_component.rs
- crates/library_checker/src/graph/two_edge_connected_components.rs
- crates/library_checker/src/tree/vertex_add_subtree_sum.rs
- crates/aizu_online_judge/src/grl/grl_5_d.rs
- crates/aizu_online_judge/src/grl/grl_5_e.rs
- crates/library_checker/src/data_structure/persistent_unionfind.rs
- crates/competitive/src/graph/dulmage_mendelsohn_decomposition.rs
- crates/competitive/src/algorithm/doubling.rs
- crates/competitive/src/tree/centroid_decomposition.rs
pub fn reverse_graph(&self) -> SparseGraph<D>
Source§impl SparseGraph<UndirectedEdge>
impl SparseGraph<UndirectedEdge>
Sourcepub fn centroid_decomposition(
&self,
f: impl FnMut(&[usize], &[usize], usize, usize),
)
pub fn centroid_decomposition( &self, f: impl FnMut(&[usize], &[usize], usize, usize), )
1/3 centroid decomposition
Examples found in repository?
crates/competitive/src/tree/distance_frequencies.rs (lines 15-40)
4 pub fn distance_frequencies(&self) -> Vec<u64> {
5 let n = self.vertices_size();
6 let mut table = vec![0u64; n];
7 if n == 0 {
8 return table;
9 }
10 table[0] = n as u64;
11 if n == 1 {
12 return table;
13 }
14 table[1] = (n * 2 - 2) as u64;
15 self.centroid_decomposition(|parents, vs, lsize, _rsize| {
16 let n = vs.len();
17 let mut dist = vec![0usize; n];
18 for i in 1..n {
19 dist[i] = dist[parents[i]] + 1;
20 }
21 let d_max = dist.iter().max().cloned().unwrap_or_default();
22 let mut f = vec![0u64; d_max + 1];
23 let mut g = vec![0u64; d_max + 1];
24 for i in 1..=lsize {
25 f[dist[i]] += 1;
26 }
27 for i in lsize + 1..n {
28 g[dist[i]] += 1;
29 }
30 while f.last().is_some_and(|&x| x == 0) {
31 f.pop();
32 }
33 while g.last().is_some_and(|&x| x == 0) {
34 g.pop();
35 }
36 let h = U64Convolve::convolve(f, g);
37 for (i, &x) in h.iter().enumerate() {
38 table[i] += x * 2;
39 }
40 });
41 table
42 }Sourcepub fn contour_query_range(&self) -> ContourQueryRange
pub fn contour_query_range(&self) -> ContourQueryRange
Examples found in repository?
crates/library_checker/src/tree/vertex_get_range_contour_add_on_tree.rs (line 17)
14pub fn vertex_get_range_contour_add_on_tree(reader: impl Read, writer: impl Write) {
15 prepare_io!(reader, writer);
16 sc!(n, q, mut a: [i64; n], (graph, _): @TreeGraphScanner::<usize, ()>::new(n));
17 let cq = graph.contour_query_range();
18 let mut bits: Vec<BinaryIndexedTree<AdditiveOperation<_>>> = cq
19 .component_sizes()
20 .map(|n| BinaryIndexedTree::new(n + 1))
21 .collect();
22
23 for _ in 0..q {
24 sc!(query: Query);
25 match query {
26 Query::Add { v, l, r, x } => {
27 cq.for_each_contour_range(v, l, r, |c, start, end| {
28 bits[c].update(start, x);
29 bits[c].update(end, -x);
30 });
31 if l == 0 && 0 < r {
32 a[v] += x;
33 }
34 }
35 Query::Get { v } => {
36 let mut ans = a[v];
37 cq.for_each_index(v, |c, i| ans += bits[c].accumulate(i));
38 pp!(ans);
39 }
40 }
41 }
42}More examples
crates/library_checker/src/tree/vertex_add_range_contour_sum_on_tree.rs (line 17)
14pub fn vertex_add_range_contour_sum_on_tree(reader: impl Read, writer: impl Write) {
15 prepare_io!(reader, writer);
16 sc!(n, q, mut a: [i64; n], (graph, _): @TreeGraphScanner::<usize, ()>::new(n));
17 let cq = graph.contour_query_range();
18 let mut raw: Vec<_> = cq.component_sizes().map(|n| vec![0; n]).collect();
19 for (v, &x) in a.iter().enumerate() {
20 cq.for_each_index(v, |c, i| raw[c][i] += x);
21 }
22 let mut bits: Vec<BinaryIndexedTree<AdditiveOperation<_>>> = raw
23 .into_iter()
24 .map(|values| BinaryIndexedTree::from_slice(&values))
25 .collect();
26 for _ in 0..q {
27 sc!(query: Query);
28 match query {
29 Query::Add { p, x } => {
30 a[p] += x;
31 cq.for_each_index(p, |c, i| bits[c].update(i, x));
32 }
33 Query::Sum { v, l, r } => {
34 let mut ans = if l == 0 && 0 < r { a[v] } else { 0 };
35 cq.for_each_contour_range(v, l, r, |c, start, end| {
36 ans += bits[c].fold_abelian(start, end);
37 });
38 pp!(ans);
39 }
40 }
41 }
42}Source§impl SparseGraph<UndirectedEdge>
impl SparseGraph<UndirectedEdge>
Sourcefn weighted_depth_dfs<M, F>(
&self,
u: usize,
p: usize,
d: M::T,
depth: &mut Vec<M::T>,
weight: &F,
)
fn weighted_depth_dfs<M, F>( &self, u: usize, p: usize, d: M::T, depth: &mut Vec<M::T>, weight: &F, )
Examples found in repository?
crates/competitive/src/tree/depth.rs (line 34)
21 fn weighted_depth_dfs<M, F>(
22 &self,
23 u: usize,
24 p: usize,
25 d: M::T,
26 depth: &mut Vec<M::T>,
27 weight: &F,
28 ) where
29 M: Monoid,
30 F: Fn(usize) -> M::T,
31 {
32 for a in self.neighbors(u).filter(|a| a.to != p) {
33 let nd = M::operate(&d, &weight(a.label));
34 self.weighted_depth_dfs::<M, _>(a.to, u, nd, depth, weight);
35 }
36 depth[u] = d;
37 }
38 pub fn weighted_tree_depth<M: Monoid, F: Fn(usize) -> M::T>(
39 &self,
40 root: usize,
41 weight: F,
42 ) -> Vec<M::T> {
43 let mut depth = vec![M::unit(); self.vertices_size()];
44 self.weighted_depth_dfs::<M, _>(root, usize::MAX, M::unit(), &mut depth, &weight);
45 depth
46 }Sourcepub fn weighted_tree_depth<M: Monoid, F: Fn(usize) -> M::T>(
&self,
root: usize,
weight: F,
) -> Vec<M::T>
pub fn weighted_tree_depth<M: Monoid, F: Fn(usize) -> M::T>( &self, root: usize, weight: F, ) -> Vec<M::T>
Examples found in repository?
crates/aizu_online_judge/src/grl/grl_5_a.rs (line 8)
5pub fn grl_5_a(reader: impl Read, writer: impl Write) {
6 prepare_io!(reader, writer);
7 sc!(n, (graph, w): @TreeGraphScanner::<usize, u64>::new(n));
8 let d = graph.weighted_tree_depth::<AdditiveOperation<_>, _>(0, |eid| w[eid]);
9 let r = (0..n).max_by_key(|&u| d[u]).unwrap();
10 let ans = graph
11 .weighted_tree_depth::<AdditiveOperation<_>, _>(r, |eid| w[eid])
12 .into_iter()
13 .max()
14 .unwrap();
15 pp!(ans);
16}Source§impl SparseGraph<UndirectedEdge>
impl SparseGraph<UndirectedEdge>
Sourcefn size_dfs(&self, u: usize, p: usize, size: &mut Vec<u64>)
fn size_dfs(&self, u: usize, p: usize, size: &mut Vec<u64>)
Examples found in repository?
crates/competitive/src/tree/depth.rs (line 54)
51 fn size_dfs(&self, u: usize, p: usize, size: &mut Vec<u64>) {
52 size[u] = 1;
53 for a in self.neighbors(u).filter(|a| a.to != p) {
54 self.size_dfs(a.to, u, size);
55 size[u] += size[a.to];
56 }
57 }
58 pub fn tree_size(&self, root: usize) -> Vec<u64> {
59 let mut size = vec![0; self.vertices_size()];
60 self.size_dfs(root, usize::MAX, &mut size);
61 size
62 }pub fn tree_size(&self, root: usize) -> Vec<u64>
Source§impl SparseGraph<UndirectedEdge>
impl SparseGraph<UndirectedEdge>
Sourcepub fn distance_frequencies(&self) -> Vec<u64>
pub fn distance_frequencies(&self) -> Vec<u64>
Source§impl SparseGraph<UndirectedEdge>
impl SparseGraph<UndirectedEdge>
pub fn subtree_euler_tour_builder<'a>( &'a self, root: usize, ) -> EulerTourBuilder<'a, First>
Sourcepub fn path_euler_tour_builder<'a>(
&'a self,
root: usize,
) -> EulerTourBuilder<'a, FirstLast>
pub fn path_euler_tour_builder<'a>( &'a self, root: usize, ) -> EulerTourBuilder<'a, FirstLast>
Examples found in repository?
crates/aizu_online_judge/src/grl/grl_5_d.rs (line 23)
15pub fn grl_5_d(reader: impl Read, writer: impl Write) {
16 prepare_io!(reader, writer);
17 sc!(n, c: [SizedCollect<usize>; iter n]);
18 let edges = c
19 .enumerate()
20 .flat_map(|(u, it)| it.into_iter().map(move |v| (u, v)))
21 .collect();
22 let graph = UndirectedSparseGraph::from_edges(n, edges);
23 let et = graph.path_euler_tour_builder(0).build();
24 let mut bit = BinaryIndexedTree::<AdditiveOperation<_>>::new(et.size);
25
26 sc!(q);
27 for _ in 0..q {
28 sc!(query: Query);
29 match query {
30 Query::Add { v, w } => {
31 et.update(v, w, -w, |k, x| bit.update(k, x));
32 }
33 Query::Get { u } => {
34 let ans = et.fold(u, |k| bit.accumulate(k));
35 pp!(ans);
36 }
37 }
38 }
39}pub fn full_euler_tour_builder<'a>( &'a self, root: usize, ) -> EulerTourBuilder<'a, Visit>
Sourcepub fn lca(&self, root: usize) -> LowestCommonAncestor
pub fn lca(&self, root: usize) -> LowestCommonAncestor
Examples found in repository?
crates/aizu_online_judge/src/grl/grl_5_c.rs (line 13)
5pub fn grl_5_c(reader: impl Read, writer: impl Write) {
6 prepare_io!(reader, writer);
7 sc!(n, c: [SizedCollect<usize>; iter n]);
8 let edges = c
9 .enumerate()
10 .flat_map(|(u, it)| it.into_iter().map(move |v| (u, v)))
11 .collect();
12 let tree = UndirectedSparseGraph::from_edges(n, edges);
13 let lca = tree.lca(0);
14 sc!(q, uv: [(usize, usize); iter q]);
15 for (u, v) in uv {
16 pp!(lca.lca(u, v));
17 }
18}More examples
crates/library_checker/src/tree/jump_on_tree.rs (line 20)
16pub fn jump_on_tree_level_ancestor(reader: impl Read, writer: impl Write) {
17 prepare_io!(reader, writer);
18 sc!(n, q, (g, _): @TreeGraphScanner::<usize>::new(n));
19 let la = g.level_ancestor(0);
20 let lca = g.lca(0);
21 for _ in 0..q {
22 sc!(s, t, i);
23 let l = lca.lca(s, t);
24 let dl = la.depth(l);
25 let ds = la.depth(s) - dl;
26 let dt = la.depth(t) - dl;
27 let ans = if i <= ds {
28 la.la(s, i)
29 } else if i <= ds + dt {
30 la.la(t, ds + dt - i)
31 } else {
32 None
33 };
34 pp!(ans.unwrap_or(!0) as isize);
35 }
36}
37
38#[verify::library_checker("jump_on_tree")]
39pub fn jump_on_tree_level_ancestor_batch(reader: impl Read, writer: impl Write) {
40 prepare_io!(reader, writer);
41 sc!(n, q, (g, _): @TreeGraphScanner::<usize>::new(n), queries: [(usize, usize, usize); iter q]);
42 let lca = g.lca(0);
43 let results = g.level_ancestor_batch(
44 0,
45 queries.map(|(s, t, i)| {
46 let l = lca.lca(s, t);
47 let dl = lca.depth(l);
48 let ds = lca.depth(s) - dl;
49 let dt = lca.depth(t) - dl;
50 if i <= ds {
51 (s, i)
52 } else if i <= ds + dt {
53 (t, ds + dt - i)
54 } else {
55 (0, n)
56 }
57 }),
58 );
59 pp!(@lf @it results.iter().map(|&v| v.unwrap_or(!0) as isize));
60}Source§impl SparseGraph<UndirectedEdge>
impl SparseGraph<UndirectedEdge>
Sourcepub fn hld(&self, root: usize) -> HeavyLightDecomposition
pub fn hld(&self, root: usize) -> HeavyLightDecomposition
Examples found in repository?
More examples
crates/library_checker/src/tree/vertex_set_path_composite.rs (line 17)
14pub fn vertex_set_path_composite(reader: impl Read, writer: impl Write) {
15 prepare_io!(reader, writer);
16 sc!(n, q, ab: [(M, M); n], (graph, _): @TreeGraphScanner::<usize, ()>::new(n));
17 let hld = graph.hld(0);
18 let mut fold = hld.build_fold::<LinearOperation<_>>(&ab);
19 for _ in 0..q {
20 sc!(query: Query);
21 match query {
22 Query::Set { p, cd } => {
23 fold.set(p, cd);
24 }
25 Query::Apply { u, v, x } => {
26 let (a, b) = fold.fold_vertices(u, v);
27 pp!(a * x + b);
28 }
29 }
30 }
31}crates/library_checker/src/tree/vertex_add_subtree_sum.rs (line 43)
38pub fn vertex_add_subtree_sum_hld(reader: impl Read, writer: impl Write) {
39 prepare_io!(reader, writer);
40 sc!(n, q, a: [u64; n], p: [usize; iter n - 1]);
41 let edges = p.enumerate().map(|(i, p)| (i + 1, p)).collect();
42 let tree = UndirectedSparseGraph::from_edges(n, edges);
43 let hld = tree.hld(0);
44 let mut b = vec![0; n];
45 for (v, x) in a.into_iter().enumerate() {
46 b[hld.index(v)] = x;
47 }
48 let mut seg = SegmentTree::<AdditiveOperation<_>>::from_vec(b);
49 for _ in 0..q {
50 sc!(query: Query);
51 match query {
52 Query::Add { u, x } => seg.update(hld.index(u), x),
53 Query::Sum { u } => {
54 pp!(seg.fold(hld.subtree_range(u)));
55 }
56 }
57 }
58}crates/aizu_online_judge/src/grl/grl_5_e.rs (line 23)
15pub fn grl_5_e(reader: impl Read, writer: impl Write) {
16 prepare_io!(reader, writer);
17 sc!(n, c: [SizedCollect<usize>; iter n]);
18 let edges = c
19 .enumerate()
20 .flat_map(|(u, it)| it.into_iter().map(move |v| (u, v)))
21 .collect();
22 let graph = UndirectedSparseGraph::from_edges(n, edges);
23 let hld = graph.hld(0);
24 let mut seg = LazySegmentTree::<RangeSumRangeAdd<_>>::from_keys(std::iter::repeat_n(0u64, n));
25
26 sc!(q);
27 for _ in 0..q {
28 sc!(query: Query);
29 match query {
30 Query::Add { v, w } => {
31 hld.path_edges(0, v, |l, r| seg.update(l..r, w));
32 }
33 Query::Get { u } => {
34 let mut ans = 0;
35 hld.path_edges(0, u, |l, r| ans += seg.fold(l..r).0);
36 pp!(ans);
37 }
38 }
39 }
40}Source§impl SparseGraph<UndirectedEdge>
impl SparseGraph<UndirectedEdge>
Sourcepub fn level_ancestor(&self, root: usize) -> LevelAncestor
pub fn level_ancestor(&self, root: usize) -> LevelAncestor
Examples found in repository?
crates/library_checker/src/tree/jump_on_tree.rs (line 19)
16pub fn jump_on_tree_level_ancestor(reader: impl Read, writer: impl Write) {
17 prepare_io!(reader, writer);
18 sc!(n, q, (g, _): @TreeGraphScanner::<usize>::new(n));
19 let la = g.level_ancestor(0);
20 let lca = g.lca(0);
21 for _ in 0..q {
22 sc!(s, t, i);
23 let l = lca.lca(s, t);
24 let dl = la.depth(l);
25 let ds = la.depth(s) - dl;
26 let dt = la.depth(t) - dl;
27 let ans = if i <= ds {
28 la.la(s, i)
29 } else if i <= ds + dt {
30 la.la(t, ds + dt - i)
31 } else {
32 None
33 };
34 pp!(ans.unwrap_or(!0) as isize);
35 }
36}More examples
crates/competitive/src/algorithm/doubling.rs (line 278)
183 pub fn new(size: usize, f: impl Fn(usize) -> (usize, M::T)) -> Self {
184 let (next, value): (Vec<_>, Vec<_>) = (0..size).map(f).unzip();
185
186 let mut indeg = vec![0usize; size];
187 for &to in &next {
188 indeg[to] += 1;
189 }
190 let mut in_cycle = vec![true; size];
191 let mut deq = VecDeque::new();
192 for (u, °) in indeg.iter().enumerate() {
193 if deg == 0 {
194 deq.push_back(u);
195 }
196 }
197 while let Some(u) = deq.pop_front() {
198 in_cycle[u] = false;
199 indeg[next[u]] -= 1;
200 if indeg[next[u]] == 0 {
201 deq.push_back(next[u]);
202 }
203 }
204
205 let mut cycle_id = vec![!0; size];
206 let mut cycle_pos = vec![!0; size];
207 let mut cycles = Vec::new();
208 for i in 0..size {
209 if in_cycle[i] && cycle_id[i] == !0 {
210 let mut cycle = Vec::new();
211 let mut u = i;
212 loop {
213 cycle_id[u] = cycles.len();
214 cycle_pos[u] = cycle.len();
215 cycle.push(u);
216 u = next[u];
217 if u == i {
218 break;
219 }
220 }
221 cycles.push(cycle);
222 }
223 }
224
225 let mut rev = vec![Vec::new(); size];
226 for u in 0..size {
227 rev[next[u]].push(u);
228 }
229
230 let mut depth_to_cycle = vec![0usize; size];
231 let mut cycle_entry = vec![!0; size];
232 let mut prefix_up = Vec::with_capacity(size);
233 prefix_up.resize_with(size, M::unit);
234 let mut q = VecDeque::new();
235 for i in 0..size {
236 if in_cycle[i] {
237 cycle_entry[i] = i;
238 prefix_up[i] = M::operate(&value[i], &M::unit());
239 q.push_back(i);
240 }
241 }
242 while let Some(u) = q.pop_front() {
243 for &v in &rev[u] {
244 if in_cycle[v] || cycle_entry[v] != !0 {
245 continue;
246 }
247 cycle_entry[v] = cycle_entry[u];
248 depth_to_cycle[v] = depth_to_cycle[u] + 1;
249 cycle_id[v] = cycle_id[u];
250 prefix_up[v] = M::operate(&value[v], &prefix_up[u]);
251 q.push_back(v);
252 }
253 }
254
255 let mut cycle_prefix = Vec::with_capacity(cycles.len());
256 for cycle in &cycles {
257 let len = cycle.len();
258 let mut pref = Vec::with_capacity(2 * len + 1);
259 pref.push(M::unit());
260 for i in 0..2 * len {
261 let v = cycle[i % len];
262 let next_val = M::operate(pref.last().unwrap(), &value[v]);
263 pref.push(next_val);
264 }
265 cycle_prefix.push(pref);
266 }
267
268 let root = size;
269 let mut edges = Vec::with_capacity(size);
270 for u in 0..size {
271 if in_cycle[u] {
272 edges.push((u, root));
273 } else {
274 edges.push((u, next[u]));
275 }
276 }
277 let graph = UndirectedSparseGraph::from_edges(size + 1, edges);
278 let la = graph.level_ancestor(root);
279
280 Self {
281 depth_to_cycle,
282 cycle_entry,
283 cycle_id,
284 cycle_pos,
285 cycles,
286 cycle_prefix,
287 prefix_up,
288 la,
289 }
290 }Sourcepub fn level_ancestor_batch(
&self,
root: usize,
queries: impl IntoIterator<Item = (usize, usize)>,
) -> Vec<Option<usize>>
pub fn level_ancestor_batch( &self, root: usize, queries: impl IntoIterator<Item = (usize, usize)>, ) -> Vec<Option<usize>>
Examples found in repository?
crates/library_checker/src/tree/jump_on_tree.rs (lines 43-58)
39pub fn jump_on_tree_level_ancestor_batch(reader: impl Read, writer: impl Write) {
40 prepare_io!(reader, writer);
41 sc!(n, q, (g, _): @TreeGraphScanner::<usize>::new(n), queries: [(usize, usize, usize); iter q]);
42 let lca = g.lca(0);
43 let results = g.level_ancestor_batch(
44 0,
45 queries.map(|(s, t, i)| {
46 let l = lca.lca(s, t);
47 let dl = lca.depth(l);
48 let ds = lca.depth(s) - dl;
49 let dt = lca.depth(t) - dl;
50 if i <= ds {
51 (s, i)
52 } else if i <= ds + dt {
53 (t, ds + dt - i)
54 } else {
55 (0, n)
56 }
57 }),
58 );
59 pp!(@lf @it results.iter().map(|&v| v.unwrap_or(!0) as isize));
60}Source§impl SparseGraph<UndirectedEdge>
impl SparseGraph<UndirectedEdge>
Sourcepub fn static_top_tree(&self, root: usize) -> StaticTopTree
pub fn static_top_tree(&self, root: usize) -> StaticTopTree
Examples found in repository?
crates/library_checker/src/tree/point_set_tree_path_composite_sum_fixed_root.rs (line 110)
103pub fn point_set_tree_path_composite_sum_fixed_root(reader: impl Read, writer: impl Write) {
104 prepare_io!(reader, writer);
105 sc!(n,
106 q,
107 value: [M; n],
108 (graph, edges): @TreeGraphScanner::<usize, (M, M)>::new(n));
109
110 let top_tree = graph.static_top_tree(0);
111 let mut dp = top_tree.dp::<Dp>(value, edges);
112
113 for _ in 0..q {
114 sc!(query: Query);
115 match query {
116 Query::SetVertex { v, x } => {
117 dp.set_vertex(v, x);
118 pp!(dp.fold_all().sum);
119 }
120 Query::SetEdge { e, a, b } => {
121 dp.set_edge(e, (a, b));
122 pp!(dp.fold_all().sum);
123 }
124 }
125 }
126}More examples
crates/library_checker/src/tree/point_set_tree_path_composite_sum.rs (line 144)
137pub fn point_set_tree_path_composite_sum(reader: impl Read, writer: impl Write) {
138 prepare_io!(reader, writer);
139 sc!(n,
140 q,
141 value: [M; n],
142 (graph, edges): @TreeGraphScanner::<usize, (M, M)>::new(n));
143
144 let top_tree = graph.static_top_tree(0);
145 let mut dp = top_tree.dp::<Dp>(value, edges);
146
147 for _ in 0..q {
148 sc!(query: Query);
149 match query {
150 Query::SetVertex { v, x, r } => {
151 dp.set_vertex(v, x);
152 pp!(dp.fold_path(r).reverse.sum);
153 }
154 Query::SetEdge { e, a, b, r } => {
155 dp.set_edge(e, (a, b));
156 pp!(dp.fold_path(r).reverse.sum);
157 }
158 }
159 }
160}Source§impl SparseGraph<UndirectedEdge>
impl SparseGraph<UndirectedEdge>
pub fn tree_centroid(&self) -> usize
Source§impl<D> SparseGraph<D>where
D: SparseGraphConstruction,
impl<D> SparseGraph<D>where
D: SparseGraphConstruction,
Sourcepub fn tree_order(&self, root: usize) -> (Vec<usize>, Vec<usize>)
pub fn tree_order(&self, root: usize) -> (Vec<usize>, Vec<usize>)
(order, parents)
Examples found in repository?
More examples
crates/competitive/src/tree/level_ancestor.rs (line 14)
12 pub fn level_ancestor(&self, root: usize) -> LevelAncestor {
13 let n = self.vertices_size();
14 let (order, parent) = self.tree_order(root);
15 let mut depth = vec![0; n];
16 for &u in order.iter().skip(1) {
17 depth[u] = depth[parent[u]] + 1;
18 }
19 let mut height = vec![1; n];
20 let mut heavy = vec![n; n];
21 for &u in order.iter().skip(1).rev() {
22 let p = parent[u];
23 if heavy[p] == n || height[heavy[p]] < height[u] {
24 heavy[p] = u;
25 }
26 height[p] = height[p].max(height[u] + 1);
27 }
28
29 let mut start = vec![0; n];
30 let mut index = vec![0; n];
31 let mut ladder = Vec::with_capacity(2 * n);
32 for &head in &order {
33 if head != root && heavy[parent[head]] == head {
34 continue;
35 }
36 let extension = height[head].min(depth[head]);
37 let offset = ladder.len();
38 ladder.resize(offset + extension + height[head], n);
39 let mut u = head;
40 for i in (0..extension).rev() {
41 u = parent[u];
42 ladder[offset + i] = u;
43 }
44 let mut u = head;
45 for i in extension..extension + height[head] {
46 ladder[offset + i] = u;
47 start[u] = offset;
48 index[u] = offset + i;
49 u = heavy[u];
50 }
51 }
52
53 LevelAncestor {
54 parent,
55 depth,
56 start,
57 index,
58 ladder,
59 }
60 }
61
62 pub fn level_ancestor_batch(
63 &self,
64 root: usize,
65 queries: impl IntoIterator<Item = (usize, usize)>,
66 ) -> Vec<Option<usize>> {
67 let n = self.vertices_size();
68 let mut start = vec![0; n + 1];
69 let queries: Vec<(usize, usize)> = queries.into_iter().collect();
70 for &(u, _) in &queries {
71 start[u] += 1;
72 }
73 for d in 0..n {
74 start[d + 1] += start[d];
75 }
76 let qsize = queries.len();
77 let mut batch = vec![(0, 0); qsize];
78 for (i, &(u, k)) in queries.iter().enumerate() {
79 start[u] -= 1;
80 batch[start[u]] = (k, i);
81 }
82 let (order, parent) = self.tree_order(root);
83 let mut path = Vec::with_capacity(n);
84 let mut results = vec![None; qsize];
85 for u in order {
86 while path.last().is_some_and(|&v| v != parent[u]) {
87 path.pop();
88 }
89 path.push(u);
90 for &(k, qi) in &batch[start[u]..start[u + 1]] {
91 let depth = path.len() - 1;
92 if k <= depth {
93 results[qi] = Some(path[depth - k]);
94 }
95 }
96 }
97 results
98 }crates/competitive/src/tree/rerooting.rs (line 73)
72 fn rerooting<I: Fn(&M::T, &M::T) -> M::T>(&mut self, inverse: Option<I>) {
73 let (order, parents) = self.graph.tree_order(0);
74 for &u in order.iter().skip(1).rev() {
75 let mut sum = M::unit();
76 let mut parent = None;
77 for a in self.graph.neighbors(u) {
78 if a.to == parents[u] {
79 parent = Some(a);
80 } else {
81 sum = self.merge(&sum, &self.ep[self.eidx(u, a)]);
82 }
83 }
84 let a = parent.unwrap();
85 let i = self.reidx(u, a);
86 self.ep[i] = self.add_subroot(&sum, u, a.label);
87 if inverse.is_some() {
88 self.dp[u] = sum;
89 }
90 }
91 if let Some(inverse) = inverse {
92 for u in order {
93 let sum = if u == 0 {
94 self.graph.neighbors(u).fold(M::unit(), |sum, a| {
95 self.merge(&sum, &self.ep[self.eidx(u, a)])
96 })
97 } else {
98 let a = self
99 .graph
100 .neighbors(u)
101 .find(|a| a.to == parents[u])
102 .unwrap();
103 self.merge(&self.dp[u], &self.ep[self.eidx(u, a)])
104 };
105 self.dp[u] = self.add_root(&sum, u);
106 for a in self.graph.neighbors(u) {
107 if a.to != parents[u] {
108 let value = inverse(&sum, &self.ep[self.eidx(u, a)]);
109 let i = self.reidx(u, a);
110 self.ep[i] = self.add_subroot(&value, u, a.label);
111 }
112 }
113 }
114 return;
115 }
116 let mut prefix = Vec::new();
117 for u in order {
118 prefix.clear();
119 prefix.push(M::unit());
120 for a in self.graph.neighbors(u) {
121 prefix.push(self.merge(prefix.last().unwrap(), &self.ep[self.eidx(u, a)]));
122 }
123 self.dp[u] = self.add_root(prefix.last().unwrap(), u);
124 let mut suffix = M::unit();
125 for (k, a) in self.graph.neighbors(u).enumerate().rev() {
126 if a.to != parents[u] {
127 let i = self.reidx(u, a);
128 self.ep[i] = self.add_subroot(&self.merge(&prefix[k], &suffix), u, a.label);
129 }
130 suffix = self.merge(&self.ep[self.eidx(u, a)], &suffix);
131 }
132 }
133 }crates/competitive/src/tree/centroid_decomposition.rs (line 272)
258 pub fn contour_query_range(&self) -> ContourQueryRange {
259 let n = self.vertices_size();
260 assert!(n <= u32::MAX as usize / 2);
261 if n <= 1 {
262 return ContourQueryRange {
263 comp_range: vec![0],
264 info_indptr: vec![0; n + 1],
265 infos: vec![],
266 local_info: vec![(usize::MAX, 0); n],
267 local_offsets: vec![],
268 local_masks: vec![],
269 };
270 }
271 let (vertices, graph) = {
272 let (vertices, parents) = self.tree_order(0);
273 let mut indices = vec![0; n];
274 for (i, &v) in vertices.iter().enumerate() {
275 indices[v] = i;
276 }
277 let edges = vertices
278 .iter()
279 .enumerate()
280 .skip(1)
281 .map(|(i, &v)| (i, indices[parents[v]]))
282 .collect();
283 let graph = UndirectedSparseGraph::from_edges(n, edges);
284 (vertices, graph)
285 };
286 let mut comp_range = vec![0usize];
287 let mut vertex_info = Vec::with_capacity(n * (n.ilog2() as usize + 1));
288 let mut info_indptr = vec![0usize; n + 1];
289 let mut local_info = vec![(usize::MAX, 0); n];
290 let mut local_offsets = Vec::new();
291 let mut local_masks = Vec::new();
292 let mut distances = Vec::new();
293 let mut local_sizes = Vec::new();
294 let mut removed = vec![false; n];
295 let mut parents = vec![usize::MAX; n];
296 let mut sizes = vec![0usize; n];
297 let mut tasks = vec![0];
298 let mut order = Vec::with_capacity(n);
299 let mut entries = Vec::with_capacity(n);
300 let mut boundaries = Vec::new();
301 let mut groups = Vec::new();
302 while let Some(root) = tasks.pop() {
303 order.clear();
304 order.push(root);
305 parents[root] = usize::MAX;
306 let mut i = 0;
307 while i < order.len() {
308 let v = order[i];
309 sizes[v] = 1;
310 for edge in graph.neighbors(v) {
311 if !removed[edge.to] && edge.to != parents[v] {
312 parents[edge.to] = v;
313 order.push(edge.to);
314 }
315 }
316 i += 1;
317 }
318 if order.len() <= 32 {
319 let len = order.len();
320 if len > 1 {
321 let comp = local_offsets.len();
322 let offset = local_masks.len();
323 local_offsets.push(offset);
324 local_sizes.push(len);
325 local_masks.resize(offset + len * (len + 1), 0u32);
326 distances.clear();
327 distances.resize(len * len, 0u8);
328 for (i, &v) in order.iter().enumerate() {
329 local_info[vertices[v]] = (comp, i);
330 sizes[v] = i;
331 local_masks[offset + i * (len + 1) + 1] = 1 << i;
332 }
333 for (i, &v) in order.iter().enumerate().skip(1) {
334 let parent = sizes[parents[v]];
335 for j in 0..i {
336 let distance = distances[parent * len + j] + 1;
337 distances[i * len + j] = distance;
338 distances[j * len + i] = distance;
339 local_masks[offset + i * (len + 1) + distance as usize + 1] |= 1 << j;
340 local_masks[offset + j * (len + 1) + distance as usize + 1] |= 1 << i;
341 }
342 }
343 for row in local_masks[offset..].chunks_exact_mut(len + 1) {
344 for d in 1..=len {
345 row[d] |= row[d - 1];
346 }
347 }
348 }
349 continue;
350 }
351 let mut centroid = root;
352 for &v in order.iter().rev() {
353 if sizes[v] >= order.len().div_ceil(2) {
354 centroid = v;
355 break;
356 }
357 sizes[parents[v]] += sizes[v];
358 }
359 removed[centroid] = true;
360 entries.clear();
361 entries.push((centroid, 0));
362 boundaries.clear();
363 boundaries.extend([0, 1]);
364 for edge in graph.neighbors(centroid) {
365 let v = edge.to;
366 if removed[v] {
367 continue;
368 }
369 tasks.push(v);
370 parents[v] = centroid;
371 let mut i = entries.len();
372 entries.push((v, 1));
373 while i < entries.len() {
374 let (v, distance) = entries[i];
375 for edge in graph.neighbors(v) {
376 if !removed[edge.to] && edge.to != parents[v] {
377 parents[edge.to] = v;
378 entries.push((edge.to, distance + 1));
379 }
380 }
381 i += 1;
382 }
383 boundaries.push(entries.len());
384 }
385 groups.push((0, boundaries.len() - 1));
386 while let Some((first, last)) = groups.pop() {
387 if last - first < 2 {
388 continue;
389 }
390 let weight = boundaries[last] - boundaries[first];
391 let target = boundaries[first] + weight.div_ceil(2);
392 let mut middle =
393 first + 1 + boundaries[first + 1..last].partition_point(|&p| p < target);
394 middle = middle.min(last - 1);
395 if middle > first + 1 {
396 let x = boundaries[middle] - boundaries[first];
397 let y = boundaries[middle - 1] - boundaries[first];
398 if y.max(weight - y) < x.max(weight - x) {
399 middle -= 1;
400 }
401 }
402 for (l, r) in [(first, middle), (middle, last)] {
403 let comp = comp_range.len() - 1;
404 let mut max_distance = 0;
405 for &(v, dep) in &entries[boundaries[l]..boundaries[r]] {
406 vertex_info.push((
407 vertices[v] as u32,
408 ContourInfo {
409 comp: comp as u32,
410 dep: dep as u32,
411 },
412 ));
413 info_indptr[vertices[v] + 1] += 1;
414 max_distance = max_distance.max(dep);
415 }
416 comp_range.push(comp_range[comp] + max_distance + 1);
417 }
418 groups.extend([(middle, last), (first, middle)]);
419 }
420 }
421 for len in local_sizes {
422 comp_range.push(comp_range.last().unwrap() + len);
423 }
424 for v in 1..=n {
425 info_indptr[v] += info_indptr[v - 1];
426 }
427 let mut infos = vec![ContourInfo { comp: 0, dep: 0 }; vertex_info.len()];
428 let mut positions = info_indptr.clone();
429 for (v, info) in vertex_info {
430 let v = v as usize;
431 infos[positions[v]] = info;
432 positions[v] += 1;
433 }
434 ContourQueryRange {
435 comp_range,
436 info_indptr,
437 infos,
438 local_info,
439 local_offsets,
440 local_masks,
441 }
442 }Trait Implementations§
Source§impl<D: Clone> Clone for SparseGraph<D>
impl<D: Clone> Clone for SparseGraph<D>
Source§impl<D: Debug> Debug for SparseGraph<D>
impl<D: Debug> Debug for SparseGraph<D>
impl DirectedGraph for SparseGraph<DirectedEdge>
Source§impl<T> EdgeMap<T> for SparseGraph<DirectedEdge>
impl<T> EdgeMap<T> for SparseGraph<DirectedEdge>
type Emap = Vec<T>
fn construct_emap<F>(&self, f: F) -> Self::Emapwhere
F: FnMut() -> T,
fn emap_get<'a>(&self, map: &'a Self::Emap, eid: Self::Label) -> &'a T
fn emap_get_mut<'a>( &self, map: &'a mut Self::Emap, eid: Self::Label, ) -> &'a mut T
fn emap_set(&self, map: &mut Self::Emap, eid: Self::Label, value: T)
Source§impl<T> EdgeMap<T> for SparseGraph<UndirectedEdge>
impl<T> EdgeMap<T> for SparseGraph<UndirectedEdge>
type Emap = Vec<T>
fn construct_emap<F>(&self, f: F) -> Self::Emapwhere
F: FnMut() -> T,
fn emap_get<'a>(&self, map: &'a Self::Emap, eid: Self::Label) -> &'a T
fn emap_get_mut<'a>( &self, map: &'a mut Self::Emap, eid: Self::Label, ) -> &'a mut T
fn emap_set(&self, map: &mut Self::Emap, eid: Self::Label, value: T)
Source§impl From<&SparseGraph<UndirectedEdge>> for RootedTree
impl From<&SparseGraph<UndirectedEdge>> for RootedTree
Source§fn from(graph: &UndirectedSparseGraph) -> Self
fn from(graph: &UndirectedSparseGraph) -> Self
Converts to this type from the input type.
Source§impl<D> Graph for SparseGraph<D>where
D: SparseGraphConstruction,
impl<D> Graph for SparseGraph<D>where
D: SparseGraphConstruction,
type Vertex = usize
type Label = usize
type Vertices<'g> = Range<usize> where D: 'g
type Neighbors<'g> = Copied<Iter<'g, Neighbor<usize, usize>>> where D: 'g
fn vsize(&self) -> usize
fn vertices(&self) -> Self::Vertices<'_>
fn neighbors(&self, vertex: Self::Vertex) -> Self::Neighbors<'_>
Source§impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for PruferSequence<T>
impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for PruferSequence<T>
Source§impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for PathTree<T>
impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for PathTree<T>
Source§impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for StarTree<T>
impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for StarTree<T>
Source§impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for MixedTree<T>
impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for MixedTree<T>
Source§impl<D, T> VertexMap<T> for SparseGraph<D>where
D: SparseGraphConstruction,
impl<D, T> VertexMap<T> for SparseGraph<D>where
D: SparseGraphConstruction,
type Vmap = Vec<T>
fn construct_vmap<F>(&self, f: F) -> Self::Vmapwhere
F: FnMut() -> T,
fn vmap_get<'a>(&self, map: &'a Self::Vmap, vid: Self::Vertex) -> &'a T
fn vmap_get_mut<'a>( &self, map: &'a mut Self::Vmap, vid: Self::Vertex, ) -> &'a mut T
fn vmap_set(&self, map: &mut Self::Vmap, vertex: Self::Vertex, value: T)
Auto Trait Implementations§
impl<D> Freeze for SparseGraph<D>
impl<D> RefUnwindSafe for SparseGraph<D>
impl<D> Send for SparseGraph<D>
impl<D> Sync for SparseGraph<D>
impl<D> Unpin for SparseGraph<D>
impl<D> UnsafeUnpin for SparseGraph<D>
impl<D> UnwindSafe for SparseGraph<D>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more