Contents Menu Expand Light mode Dark mode Auto light/dark, in light mode Auto light/dark, in dark mode Skip to content
titan_pylib documentation
titan_pylib documentation
  • ahc
    • ahc_settings
    • calc_ratio
    • optimizer
    • parallel_tester
  • algorithm
    • random
      • random
      • random_graph
      • random_tree
    • sort
      • bubble_sort
      • merge_sort
      • quick_sort
    • arithmetic_progression
    • cycle_memo
    • doubling
    • gray_code
    • mo
    • parser
    • permutation
  • data_structures
    • array
      • array_2D
      • csr_array
      • partial_persistent_array
      • persistent_array
    • avl_tree
      • avl_tree_dict
      • avl_tree_multiset
      • avl_tree_multiset2
      • avl_tree_multiset3
      • avl_tree_set
      • avl_tree_set2
      • avl_tree_set3
      • lazy_avl_tree
      • persistent_avl_tree_list
      • persistent_lazy_avl_tree
      • reversible_lazy_avl_tree
      • wbt_set
    • b_tree
      • b_tree_list
      • b_tree_set
    • binary_trie
      • binary_trie_multiset
      • binary_trie_set
    • bit_vector
      • avl_tree_bit_vector
      • bit_vector
      • bit_vector_interface
      • splay_tree_bit_vector
    • bst_base
      • bst_multiset_array_base
      • bst_multiset_node_base
      • bst_set_node_base
    • cumulative_sum
      • cumulative_op
      • cumulative_sum
      • cumulative_sum2D
    • deque
      • deque
      • foldable_deque
    • dict
      • hash_dict
    • dynamic_connectivity
      • euler_tour_tree
      • lazy_link_cut_tree
      • link_cut_tree
      • offline_dynamic_connectivity
    • fenwick_tree
      • dynamic_fenwick_tree
      • dynamic_fenwick_tree_2D
      • fenwick_tree
      • fenwick_tree_2D
      • fenwick_tree_2D_RAQ
      • fenwick_tree_RAQ
      • fenwick_tree_abst
    • heap
      • Randomized_meldable_heap
      • binomial_heap
      • deletable_max_heap
      • deletable_min_heap
      • double_ended_heap
      • max_heap
      • min_heap
      • radix_heap
    • list
      • linked_list
    • merge_sort_tree
      • merge_sort_tree
    • others
      • pair
    • rbst
      • lazy_rbst
    • red_black_tree
      • red_black_tree_multiset
      • red_black_tree_set
    • safe_hash
      • hash_counter
      • hash_defaultdict
      • hash_dict
      • hash_set
    • scapegoat_tree
      • scapegoat_tree_multiset
      • scapegoat_tree_set
    • segment_quadratic_division
      • quadratic_division_list
      • segment_lazy_quadratic_division
      • segment_quadratic_division
    • segment_tree
      • dual_commutative_segment_tree
      • dual_segment_tree
      • dual_segment_tree_commutative
      • dynamic_segment_tree
      • lazy_segment_tree
      • lazy_segment_tree_range
      • persistent_segment_tree
      • range_set_range_composite
      • segment_tree
      • segment_tree_RSQ
      • segment_tree_RmQ
      • segment_tree_interface
    • set
      • dynamic_fenwick_tree_multiset
      • dynamic_fenwick_tree_set
      • fenwick_tree_multiset
      • fenwick_tree_set
      • fenwick_tree_set_fast
      • hash_set
      • hashed_multiset
      • mex_multiset
      • min_max_multiset
      • min_max_set
      • multiset_quadratic_division
      • range_set
      • segki_set
      • set_quadratic_division
      • sorted_multiset
      • sorted_set
      • static_ordered_multiset
      • static_ordered_set
      • wordsize_tree_multiset
      • wordsize_tree_set
    • sparse_table
      • sparse_table
      • sparse_table_RmQ
    • splay_tree
      • lazy_splay_tree
      • lazy_splay_tree_array
      • reversible_lazy_splay_tree_array
      • splay_tree_dict
      • splay_tree_list
      • splay_tree_list_array
      • splay_tree_multiset
      • splay_tree_multiset2
      • splay_tree_multiset_sum
      • splay_tree_multiset_top_down
      • splay_tree_set
      • splay_tree_set_top_down
    • stack
      • foldable_stack
      • persistent_stack
      • stack
    • static_array_query
      • static_RmQ
      • static_range_mode_query
    • treap
      • treap_multiset
      • treap_set
    • union_find
      • fully_retroactive_union_find
      • partial_persistent_union_find
      • persistent_union_find
      • undoable_union_find
      • union_find
      • union_find_heavy
      • union_find_members
      • weighted_union_find
    • wavelet_matrix
      • cumulative_sum_wavelet_matrix
      • dynamic_wavelet_matrix
      • fenwick_tree_wavelet_matrix
      • wavelet_matrix
    • wbt
      • wbt_lazy_list
      • wbt_list
      • wbt_multiset
      • wbt_set
  • geometry
    • geometry
  • graph
    • flow
      • bipartite_max_matching
      • max_flow_dinic
      • max_flow_ford_fulkerson
    • hld
      • hld
      • hld_lazy_segment_tree
      • hld_noncommutative_segment_tree
      • hld_segment_tree
    • bellman_ford
    • bfs
    • cartesian_tree
    • dfs_tree
    • dijkstra
    • euler_tour
    • functional_graph
    • get_articulation_points
    • get_biconnected_components
    • get_bridge
    • get_scc
    • get_scc_graph
    • get_scc_lowlink
    • grid_bfs
    • is_bipartite_graph
    • lca
    • namori
    • perfect_binary_tree
    • rerooting_dp
    • rooted_tree
    • spfa
    • topological_sort
    • warshall_floyd
    • weighted_rooted_tree
  • io
    • fast_o
  • math
    • affine_map
    • big_int
    • comb
    • decimal_util
    • divisors
    • fraction
    • get_quotients
    • is_prime64
    • mod_array
    • mod_comb
    • mod_int
    • mod_int_1000000007
    • mod_int_998244353
    • mod_matrix
    • number
    • pollard_rho
  • string
    • dynamic_hash_string
    • get_suffix_array
    • hash_string
    • multi_hash_string
    • string_count
    • trie
Back to top
View this page

get_scc_lowlink¶

ソースコード¶

from titan_pylib.graph.get_scc_lowlink import get_scc_lowlink

view on github

展開済みコード¶

  1# from titan_pylib.graph.get_scc_lowlink import get_scc_lowlink
  2# from titan_pylib.others.antirec import antirec
  3from types import GeneratorType
  4
  5# ref: https://github.com/cheran-senthil/PyRival/blob/master/pyrival/misc/bootstrap.py
  6# ref: https://twitter.com/onakasuita_py/status/1731535542305907041
  7
  8
  9def antirec(func):
 10    stack = []
 11
 12    def wrappedfunc(*args, **kwargs):
 13        if stack:
 14            return func(*args, **kwargs)
 15        to = func(*args, **kwargs)
 16        while True:
 17            if isinstance(to, GeneratorType):
 18                stack.append(to)
 19                to = next(to)
 20            else:
 21                stack.pop()
 22                if not stack:
 23                    break
 24                to = stack[-1].send(to)
 25        return to
 26
 27    return wrappedfunc
 28
 29
 30def antirec_cache(func):
 31    stack = []
 32    memo = {}
 33    args_list = []
 34
 35    def wrappedfunc(*args):
 36        args_list.append(args)
 37        if stack:
 38            return func(*args)
 39        to = func(*args)
 40        while True:
 41            if args_list[-1] in memo:
 42                res = memo[args_list.pop()]
 43                if not stack:
 44                    return res
 45                to = stack[-1].send(res)
 46                continue
 47            if isinstance(to, GeneratorType):
 48                stack.append(to)
 49                to = next(to)
 50            else:
 51                memo[args_list.pop()] = to
 52                stack.pop()
 53                if not stack:
 54                    break
 55                to = stack[-1].send(to)
 56        return to
 57
 58    return wrappedfunc
 59
 60
 61def get_scc_lowlink(G: list[list[int]]) -> list[list[int]]:
 62    n = len(G)
 63    stack = [0] * n
 64    ptr = 0
 65    lowlink = [-1] * n
 66    order = [-1] * n
 67    ids = [0] * n
 68    cur_time = 0
 69    group_cnt = 0
 70
 71    @antirec
 72    def dfs(v: int):
 73        nonlocal cur_time, ptr
 74        order[v] = cur_time
 75        lowlink[v] = cur_time
 76        cur_time += 1
 77        stack[ptr] = v
 78        ptr += 1
 79        for x in G[v]:
 80            if order[x] == -1:
 81                yield dfs(x)
 82                lowlink[v] = min(lowlink[v], lowlink[x])
 83            else:
 84                lowlink[v] = min(lowlink[v], order[x])
 85        if lowlink[v] == order[v]:
 86            nonlocal group_cnt
 87            while True:
 88                u = stack[ptr - 1]
 89                ptr -= 1
 90                order[u] = n
 91                ids[u] = group_cnt
 92                if u == v:
 93                    break
 94            group_cnt += 1
 95        yield
 96
 97    for v in range(n):
 98        if order[v] == -1:
 99            dfs(v)
100    groups = [[] for _ in range(group_cnt)]
101    for v in range(n):
102        groups[group_cnt - 1 - ids[v]].append(v)
103    return groups

仕様¶

get_scc_lowlink(G: list[list[int]]) → list[list[int]][source]¶
Next
grid_bfs
Previous
get_scc_graph
Copyright © 2024, titan
Made with Sphinx and @pradyunsg's Furo
On this page
  • get_scc_lowlink
    • ソースコード
      • 展開済みコード
    • 仕様
      • get_scc_lowlink()