module AtCoder.Scc (SccGraph, nScc, new, addEdge, scc) where
import AtCoder.Internal.Assert qualified as ACIA
import AtCoder.Internal.Scc qualified as ACISCC
import Control.Monad.Primitive (PrimMonad, PrimState)
import Data.Vector qualified as V
import Data.Vector.Unboxed qualified as VU
import GHC.Stack (HasCallStack)
newtype SccGraph s = SccGraph (ACISCC.SccGraph s)
{-# INLINE nScc #-}
nScc :: SccGraph s -> Int
nScc :: forall s. SccGraph s -> Int
nScc (SccGraph SccGraph s
g) = SccGraph s -> Int
forall s. SccGraph s -> Int
ACISCC.nScc SccGraph s
g
{-# INLINE new #-}
new :: (PrimMonad m) => Int -> m (SccGraph (PrimState m))
new :: forall (m :: * -> *).
PrimMonad m =>
Int -> m (SccGraph (PrimState m))
new Int
n = SccGraph (PrimState m) -> SccGraph (PrimState m)
forall s. SccGraph s -> SccGraph s
SccGraph (SccGraph (PrimState m) -> SccGraph (PrimState m))
-> m (SccGraph (PrimState m)) -> m (SccGraph (PrimState m))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> m (SccGraph (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (SccGraph (PrimState m))
ACISCC.new Int
n
{-# INLINE addEdge #-}
addEdge :: (HasCallStack, PrimMonad m) => SccGraph (PrimState m) -> Int -> Int -> m ()
addEdge :: forall (m :: * -> *).
(HasCallStack, PrimMonad m) =>
SccGraph (PrimState m) -> Int -> Int -> m ()
addEdge (SccGraph SccGraph (PrimState m)
gr) Int
from Int
to = do
let n :: Int
n = SccGraph (PrimState m) -> Int
forall s. SccGraph s -> Int
ACISCC.nScc SccGraph (PrimState m)
gr
let !()
_ = HasCallStack => String -> String -> Int -> String -> Int -> ()
String -> String -> Int -> String -> Int -> ()
ACIA.checkCustom String
"AtCoder.Scc.addEdge" String
"`from` vertex" Int
from String
"the number of vertices" Int
n
let !()
_ = HasCallStack => String -> String -> Int -> String -> Int -> ()
String -> String -> Int -> String -> Int -> ()
ACIA.checkCustom String
"AtCoder.Scc.addEdge" String
"`to` vertex" Int
to String
"the number of vertices" Int
n
SccGraph (PrimState m) -> Int -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
SccGraph (PrimState m) -> Int -> Int -> m ()
ACISCC.addEdge SccGraph (PrimState m)
gr Int
from Int
to
{-# INLINE scc #-}
scc :: (PrimMonad m) => SccGraph (PrimState m) -> m (V.Vector (VU.Vector Int))
scc :: forall (m :: * -> *).
PrimMonad m =>
SccGraph (PrimState m) -> m (Vector (Vector Int))
scc (SccGraph SccGraph (PrimState m)
g) = SccGraph (PrimState m) -> m (Vector (Vector Int))
forall (m :: * -> *).
PrimMonad m =>
SccGraph (PrimState m) -> m (Vector (Vector Int))
ACISCC.scc SccGraph (PrimState m)
g