Skip to main content

SparseGraph

Struct SparseGraph 

Source
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 SparseGraph<DirectedEdge>

Source

pub fn to_graphvis<N, NA, E, EA>(&self, node_attr: N, edge_attr: E) -> String
where N: Fn(usize) -> NA, E: Fn(usize) -> EA, NA: Display, EA: Display,

Source§

impl SparseGraph<UndirectedEdge>

Source

pub fn to_graphvis<N, NA, E, EA>(&self, node_attr: N, edge_attr: E) -> String
where N: Fn(usize) -> NA, E: Fn(usize) -> EA, NA: Display, EA: Display,

Source§

impl SparseGraph<BidirectionalEdge>

Source

pub fn to_graphvis<N, NA, E, EA>(&self, node_attr: N, edge_attr: E) -> String
where N: Fn(usize) -> NA, E: Fn(usize) -> EA, NA: Display, EA: Display,

Source§

impl<D> SparseGraph<D>

Source

pub fn vertices_size(&self) -> usize

Return the number of vertices.

Examples found in repository?
crates/competitive/src/graph/sparse_graph.rs (line 36)
35    pub fn vertices(&self) -> ops::Range<usize> {
36        0..self.vertices_size()
37    }
More examples
Hide additional 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    }
Source

pub fn edges_size(&self) -> usize

Return the number of edges.

Examples found in repository?
crates/competitive/src/tree/rerooting.rs (line 54)
53    fn eidx(&self, u: usize, a: Neighbor<usize, usize>) -> usize {
54        a.label + self.graph.edges_size() * (u > a.to) as usize
55    }
56    #[inline]
57    fn reidx(&self, u: usize, a: Neighbor<usize, usize>) -> usize {
58        a.label + self.graph.edges_size() * (u < a.to) as usize
59    }
More examples
Hide additional 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}
Source

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
Hide additional 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    }
Source

pub fn builder<T>(vsize: usize) -> SparseGraphBuilder<T, D>

Source

pub fn builder_with_esize<T>( vsize: usize, esize: usize, ) -> SparseGraphBuilder<T, D>

Source§

impl<D> SparseGraph<D>

Source

pub fn from_edges(vsize: usize, edges: Vec<(usize, usize)>) -> Self

Construct graph from edges.

Examples found in repository?
crates/competitive/src/graph/sparse_graph.rs (line 185)
184    pub fn build(self) -> (SparseGraph<D>, Vec<T>) {
185        let graph = SparseGraph::from_edges(self.vsize, self.edges);
186        (graph, self.rest)
187    }
More examples
Hide additional examples
crates/competitive/src/graph/maximum_flow.rs (line 29)
27    pub fn gen_graph(&mut self) -> BidirectionalSparseGraph {
28        let edges = std::mem::take(&mut self.edges);
29        BidirectionalSparseGraph::from_edges(self.vsize, edges)
30    }
crates/competitive/src/graph/minimum_cost_flow.rs (line 32)
30    pub fn gen_graph(&mut self) -> BidirectionalSparseGraph {
31        let edges = std::mem::take(&mut self.edges);
32        BidirectionalSparseGraph::from_edges(self.vsize, edges)
33    }
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    }
crates/library_checker/src/tree/lca.rs (line 23)
19pub fn lca_hld(reader: impl Read, writer: impl Write) {
20    prepare_io!(reader, writer);
21    sc!(n, q, p: [usize; iter n - 1]);
22    let edges = p.enumerate().map(|(i, p)| (i + 1, p)).collect();
23    let graph = UndirectedSparseGraph::from_edges(n, edges);
24    let hld = graph.hld(0);
25    for _ in 0..q {
26        sc!(u, v);
27        pp!(hld.lca(u, v));
28    }
29}
crates/library_checker/src/graph/scc.rs (line 8)
5pub fn scc(reader: impl Read, writer: impl Write) {
6    prepare_io!(reader, writer);
7    sc!(vs, es, edges: [(usize, usize); es]);
8    let graph = DirectedSparseGraph::from_edges(vs, edges);
9    let scc = StronglyConnectedComponent::new(&graph);
10    let comp = scc.components();
11    pp!(comp.len());
12    for vs in comp.into_iter() {
13        pp!(vs.len(), @it vs);
14    }
15}
Source

pub fn reverse_graph(&self) -> SparseGraph<D>

Source§

impl SparseGraph<UndirectedEdge>

Source

pub fn centroid_decomposition( &self, f: impl FnMut(&[usize], &[usize], usize, usize), )

1/3 centroid decomposition

  • f: (parents: &usize, vs: &usize, lsize: usize, rsize: usize)
  • 0: root, 1..=lsize: left subtree, lsize+1..=lsize+rsize: right subtree
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    }
Source

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
Hide additional 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>

Source

fn depth_dfs(&self, u: usize, p: usize, d: u64, depth: &mut Vec<u64>)

Examples found in repository?
crates/competitive/src/tree/depth.rs (line 9)
6    fn depth_dfs(&self, u: usize, p: usize, d: u64, depth: &mut Vec<u64>) {
7        depth[u] = d;
8        for a in self.neighbors(u).filter(|a| a.to != p) {
9            self.depth_dfs(a.to, u, d + 1, depth);
10        }
11    }
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    }
Source

pub fn tree_depth(&self, root: usize) -> Vec<u64>

Source§

impl SparseGraph<UndirectedEdge>

Source

fn weighted_depth_dfs<M, F>( &self, u: usize, p: usize, d: M::T, depth: &mut Vec<M::T>, weight: &F, )
where M: Monoid, F: Fn(usize) -> M::T,

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    }
Source

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>

Source

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    }
Source

pub fn tree_size(&self, root: usize) -> Vec<u64>

Source§

impl SparseGraph<UndirectedEdge>

Source

pub fn distance_frequencies(&self) -> Vec<u64>

Examples found in repository?
crates/library_checker/src/tree/frequency_table_of_tree_distance.rs (line 8)
5pub fn frequency_table_of_tree_distance(reader: impl Read, writer: impl Write) {
6    prepare_io!(reader, writer);
7    sc!(n, (g, _): @TreeGraphScanner::<usize>::new(n));
8    let freqs = g.distance_frequencies();
9    pp!(@it freqs[1..].iter().map(|&f| f / 2));
10}
Source§

impl SparseGraph<UndirectedEdge>

Source

pub fn subtree_euler_tour_builder<'a>( &'a self, root: usize, ) -> EulerTourBuilder<'a, First>

Source

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}
Source

pub fn full_euler_tour_builder<'a>( &'a self, root: usize, ) -> EulerTourBuilder<'a, Visit>

Source

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
Hide additional 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>

Source

pub fn hld(&self, root: usize) -> HeavyLightDecomposition

Examples found in repository?
crates/library_checker/src/tree/jump_on_tree.rs (line 8)
5pub fn jump_on_tree(reader: impl Read, writer: impl Write) {
6    prepare_io!(reader, writer);
7    sc!(n, q, (g, _): @TreeGraphScanner::<usize>::new(n));
8    let hld = g.hld(0);
9    for _ in 0..q {
10        sc!(s, t, i);
11        pp!(hld.jump(s, t, i).unwrap_or(!0) as isize);
12    }
13}
More examples
Hide additional examples
crates/library_checker/src/tree/lca.rs (line 24)
19pub fn lca_hld(reader: impl Read, writer: impl Write) {
20    prepare_io!(reader, writer);
21    sc!(n, q, p: [usize; iter n - 1]);
22    let edges = p.enumerate().map(|(i, p)| (i + 1, p)).collect();
23    let graph = UndirectedSparseGraph::from_edges(n, edges);
24    let hld = graph.hld(0);
25    for _ in 0..q {
26        sc!(u, v);
27        pp!(hld.lca(u, v));
28    }
29}
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>

Source

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
Hide additional 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, &deg) 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    }
Source

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>

Source

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
Hide additional 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>

Source

pub fn tree_center(&self) -> TreeCenter

tree center

Examples found in repository?
crates/competitive/src/tree/tree_hash.rs (line 55)
54    pub fn hash(&mut self, g: &UndirectedSparseGraph) -> u64 {
55        match g.tree_center() {
56            TreeCenter::One(u) => self.hash_rec(g, u, !0, 0),
57            TreeCenter::Two(u, v) => {
58                Self::mersenne_mul_mod(self.hash_rooted(g, u, v), self.hash_rooted(g, v, u))
59            }
60        }
61    }
Source§

impl SparseGraph<UndirectedEdge>

Source

pub fn tree_centroid(&self) -> usize

Source§

impl SparseGraph<UndirectedEdge>

Source

pub fn tree_dp_bottom_up<T, F>(&self, root: usize, dp: &mut [T], f: F)
where F: FnMut(&mut T, &T),

Source

pub fn tree_dp_top_down<T, F>(&self, root: usize, dp: &mut [T], f: F)
where F: FnMut(&mut T, &T),

Source§

impl<D> SparseGraph<D>

Source

pub fn tree_order(&self, root: usize) -> (Vec<usize>, Vec<usize>)

(order, parents)

Examples found in repository?
crates/competitive/src/tree/euler_tour.rs (line 192)
191    pub fn lca(&self, root: usize) -> LowestCommonAncestor {
192        let (order, parents) = self.tree_order(root);
193        LowestCommonAncestor::from_dfs_preorder(&parents, &order)
194    }
More examples
Hide additional 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>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<D: Debug> Debug for SparseGraph<D>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl DirectedGraph for SparseGraph<DirectedEdge>

Source§

impl<T> EdgeMap<T> for SparseGraph<DirectedEdge>

Source§

type Emap = Vec<T>

Source§

fn construct_emap<F>(&self, f: F) -> Self::Emap
where F: FnMut() -> T,

Source§

fn emap_get<'a>(&self, map: &'a Self::Emap, eid: Self::Label) -> &'a T

Source§

fn emap_get_mut<'a>( &self, map: &'a mut Self::Emap, eid: Self::Label, ) -> &'a mut T

Source§

fn emap_set(&self, map: &mut Self::Emap, eid: Self::Label, value: T)

Source§

impl<T> EdgeMap<T> for SparseGraph<UndirectedEdge>

Source§

type Emap = Vec<T>

Source§

fn construct_emap<F>(&self, f: F) -> Self::Emap
where F: FnMut() -> T,

Source§

fn emap_get<'a>(&self, map: &'a Self::Emap, eid: Self::Label) -> &'a T

Source§

fn emap_get_mut<'a>( &self, map: &'a mut Self::Emap, eid: Self::Label, ) -> &'a mut T

Source§

fn emap_set(&self, map: &mut Self::Emap, eid: Self::Label, value: T)

Source§

impl From<&SparseGraph<UndirectedEdge>> for RootedTree

Source§

fn from(graph: &UndirectedSparseGraph) -> Self

Converts to this type from the input type.
Source§

impl<D> Graph for SparseGraph<D>

Source§

type Vertex = usize

Source§

type Label = usize

Source§

type Vertices<'g> = Range<usize> where D: 'g

Source§

type Neighbors<'g> = Copied<Iter<'g, Neighbor<usize, usize>>> where D: 'g

Source§

fn vsize(&self) -> usize

Source§

fn vertices(&self) -> Self::Vertices<'_>

Source§

fn neighbors(&self, vertex: Self::Vertex) -> Self::Neighbors<'_>

Source§

impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for PruferSequence<T>

Source§

fn rand(&self, rng: &mut Xorshift) -> UndirectedSparseGraph

Return a random value.
Source§

fn rand_iter(self, rng: &mut Xorshift) -> RandIter<'_, T, Self> ⓘ

Return an iterator that generates random values.
Source§

impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for PathTree<T>

Source§

fn rand(&self, rng: &mut Xorshift) -> UndirectedSparseGraph

Return a random value.
Source§

fn rand_iter(self, rng: &mut Xorshift) -> RandIter<'_, T, Self> ⓘ

Return an iterator that generates random values.
Source§

impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for StarTree<T>

Source§

fn rand(&self, rng: &mut Xorshift) -> UndirectedSparseGraph

Return a random value.
Source§

fn rand_iter(self, rng: &mut Xorshift) -> RandIter<'_, T, Self> ⓘ

Return an iterator that generates random values.
Source§

impl<T: RandomSpec<usize>> RandomSpec<SparseGraph<UndirectedEdge>> for MixedTree<T>

Source§

fn rand(&self, rng: &mut Xorshift) -> UndirectedSparseGraph

Return a random value.
Source§

fn rand_iter(self, rng: &mut Xorshift) -> RandIter<'_, T, Self> ⓘ

Return an iterator that generates random values.
Source§

impl<D, T> VertexMap<T> for SparseGraph<D>

Source§

type Vmap = Vec<T>

Source§

fn construct_vmap<F>(&self, f: F) -> Self::Vmap
where F: FnMut() -> T,

Source§

fn vmap_get<'a>(&self, map: &'a Self::Vmap, vid: Self::Vertex) -> &'a T

Source§

fn vmap_get_mut<'a>( &self, map: &'a mut Self::Vmap, vid: Self::Vertex, ) -> &'a mut T

Source§

fn vmap_set(&self, map: &mut Self::Vmap, vertex: Self::Vertex, value: T)

Auto Trait Implementations§

§

impl<D> Freeze for SparseGraph<D>
where PhantomData<fn() -> D>: Freeze,

§

impl<D> RefUnwindSafe for SparseGraph<D>
where PhantomData<fn() -> D>: RefUnwindSafe,

§

impl<D> Send for SparseGraph<D>
where PhantomData<fn() -> D>: Send,

§

impl<D> Sync for SparseGraph<D>
where PhantomData<fn() -> D>: Sync,

§

impl<D> Unpin for SparseGraph<D>
where PhantomData<fn() -> D>: Unpin,

§

impl<D> UnsafeUnpin for SparseGraph<D>
where PhantomData<fn() -> D>: UnsafeUnpin,

§

impl<D> UnwindSafe for SparseGraph<D>
where PhantomData<fn() -> D>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<G> GraphOrderExt for G
where G: Graph + ?Sized,

Source§

fn bfs_order(&self, root: Self::Vertex) -> Vec<Self::Vertex>
where Self: VertexMap<bool>,

Source§

fn dfs_order(&self, root: Self::Vertex) -> Vec<Self::Vertex>
where Self: VertexMap<bool>,

Source§

fn dfs_tree(&self, root: Self::Vertex) -> <Self as EdgeMap<bool>>::Emap
where Self: EdgeMap<bool> + VertexMap<bool>,

Source§

fn for_each_connected_components<F>(&self, f: F)
where Self: VertexMap<bool>, F: FnMut(&Self, Self::Vertex, &[(Self::Vertex, Option<Self::Vertex>)]),

f: |g, root, ord: [vertex, parent]| {}
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<G> ShortestPathExt for G
where G: Graph + ?Sized,

Source§

fn standard_sp<'a, M>(&'a self) -> ShortestPathBuilder<'a, Self, StandardSp<M>>
where Self: Sized, M: Monoid<T: Bounded + Ord>,

Source§

fn standard_sp_additive<'a, T>( &'a self, ) -> ShortestPathBuilder<'a, Self, StandardSp<AdditiveOperation<T>>>
where Self: Sized, T: Clone + Zero + Add<Output = T> + Bounded + Ord,

Source§

fn option_sp<'a, M>(&'a self) -> ShortestPathBuilder<'a, Self, OptionSp<M>>
where Self: Sized, M: Monoid<T: Ord>,

Source§

fn option_sp_additive<'a, T>( &'a self, ) -> ShortestPathBuilder<'a, Self, OptionSp<AdditiveOperation<T>>>
where Self: Sized, T: Clone + Zero + Add<Output = T> + Ord,

Source§

fn path_folding_sp<'a, M, S>( &'a self, ) -> ShortestPathBuilder<'a, Self, PathFoldingSp<M, S>>
where Self: Sized, M: Monoid<T: Bounded + Ord>, S: SemiRing,

Source§

fn path_folding_sp_additive_addmul<'a, T, U>( &'a self, ) -> ShortestPathBuilder<'a, Self, PathFoldingSp<AdditiveOperation<T>, AddMulOperation<U>>>
where Self: Sized, T: Clone + Zero + Add<Output = T> + Bounded + Ord, U: DotProduct + One,

Source§

impl<G> SteinerTreeExt for G
where G: Graph + ?Sized,

Source§

fn steiner_tree(&self) -> SteinerTreeBuilder<'_, Self>
where Self: Sized,

Source§

impl<T> ToArrayVecScalar for T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<G> TopologicalSortExt for G
where G: DirectedGraph + ?Sized,

Source§

fn topological_sort(&self) -> Vec<Self::Vertex>
where Self: VertexMap<usize>,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.