Submission #140275


Source Code Expand

{-# OPTIONS_GHC -O2 -funbox-strict-fields #-}
{-# LANGUAGE BangPatterns, ViewPatterns, OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE MagicHash, UnboxedTuples #-}

import Control.Applicative
import Control.Arrow
import Data.Function
import qualified Data.ByteString.Char8 as S
import qualified Data.Vector as V
import qualified Data.Vector.Generic as G
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as UM
import qualified Data.IntMap as IM
import Control.Monad
import Data.Tuple

--import Debug.Trace


import GHC.ST (ST(..))
import GHC.Exts (Int(..), MutableByteArray#, newByteArray#, readIntArray#)
import GHC.Exts (writeIntArray#)

-- | Untyped byte array.
data MBA s = MBA (MutableByteArray# s)

newMBA :: Int -> ST s (MBA s)
newMBA (I# bytes) = ST $ \s -> let
  !(# s1, mba #) = newByteArray# bytes s
  in (# s1, MBA mba #)

readIntMBA :: MBA s -> Int -> ST s Int
readIntMBA (MBA mba) (I# ofs) = ST $ \s -> let
  !(# s1, val #) = readIntArray# mba ofs s
  in (# s1, I# val #)
{-# INLINE readIntMBA #-}

writeIntMBA :: MBA s -> Int -> Int -> ST s ()
writeIntMBA (MBA mba) (I# ofs) (I# val) = ST $ \s -> let
  !s1 = writeIntArray# mba ofs val s
  in (# s1, () #)
{-# INLINE writeIntMBA #-}


data MQueue s a = MQueue
  { mqSzV :: !(MBA s) -- raedp, writep
  , mqVals :: !(UM.MVector s a)
  }

newMQ :: (UM.Unbox a) => Int -> ST s (MQueue s a)
newMQ cap = MQueue
  <$> do
    r <- newMBA 16
    writeIntMBA r 0 0
    writeIntMBA r 1 0
    return r
  <*> UM.new cap

pushMQ :: (UM.Unbox a) => MQueue s a -> a -> ST s ()
pushMQ MQueue{..} (forceU -> !val) = do
  readp <- readIntMBA mqSzV 0
  writep <- readIntMBA mqSzV 1
  let !writep' = rem (writep + 1) $ UM.length mqVals
  when (writep' == readp) $ fail $
    "pushMQ: overflow (cap=" ++ show (UM.length mqVals) ++ ")"
  UM.unsafeWrite mqVals writep val
  writeIntMBA mqSzV 1 writep'
{-# INLINE pushMQ #-}

popMQ :: (UM.Unbox a) => MQueue s a -> ST s (Maybe a)
popMQ MQueue{..} = do
  readp <- readIntMBA mqSzV 0
  writep <- readIntMBA mqSzV 1
  if readp == writep
    then return Nothing
    else do
      writeIntMBA mqSzV 0 $ (readp + 1) `rem` UM.length mqVals
      Just <$> UM.unsafeRead mqVals readp
{-# INLINE popMQ #-}

forceU :: (U.Unbox a) => a -> a
forceU x = G.elemseq (vec x) x x
  where
    vec :: a -> U.Vector a
    vec = undefined
{-# INLINE forceU #-}

trace :: a -> b -> b
trace = const id

data Graph = Graph
  { gV :: !Int
  , gE :: !(V.Vector (U.Vector Int))
  }
  deriving (Show)

type GMat = [U.Vector Int]

tr :: (Show a) => String -> a -> a
tr hdr val = trace (hdr++": "++show val) val

solve :: Graph -> Graph -> (Int, Int)
solve gx gy = (max (U.maximum mdx) $ max (U.maximum mdy) $ U.minimum mdx + U.minimum mdy + 1, U.maximum mdx + U.maximum mdy + 1)
  where
    mdx = calc gx
    mdy = calc gy
    calc = maxDists . bfs

maxDists :: GMat -> U.Vector Int
maxDists = U.convert . V.map U.maximum . V.fromList

bfs :: Graph -> GMat
bfs g@Graph{..} = tr ("bfs:" ++ show g) $ map bfs1 [0..gV - 1]
  where
    bfs1 i = U.create $ do
      !mv <- UM.replicate gV inf
      !q <- newMQ 1000
      UM.unsafeWrite mv i 0
      pushMQ q i
      fix $ \fill -> do
        top <- popMQ q
        case top of
          Nothing -> return ()
          Just !x -> do
            dist <- UM.unsafeRead mv x
            let !dist' = dist + 1
            flip U.mapM_  (gE `V.unsafeIndex` x) $ \other -> do
              old' <- UM.unsafeRead mv other
              when (old' == inf) $ do
                UM.unsafeWrite mv other dist'
                pushMQ q other
            fill
      return mv

inf :: Int
inf = 1000000

main :: IO ()
main = do
  (a, b) <- solve <$> readGraph <*> readGraph
  putStrLn $ unwords $ map show [a, b]

readGraph :: IO Graph
readGraph = do
  [n,m] <- map readInt . S.words <$> S.getLine
  pairs <- replicateM m $ readPair <$> S.getLine
  let !edges = fmap (U.fromList . ($[])) $
        IM.fromListWith (.) $ map (second (:)) $
          pairs ++ map swap pairs
  return Graph{ gV=n, gE=V.fromList $ map (\i -> IM.findWithDefault U.empty i edges) [0..n-1]}

readPair :: S.ByteString -> (Int, Int)
readPair ln = 
    let ![from, to] = map readInt $ S.words ln
    in (from, to)

readInt :: S.ByteString -> Int
readInt s = case S.readInt s of
  Just (r, "") -> r
  _ -> error $ "not an integer: " ++ show s

Submission Info

Submission Time
Task C - 直径
User mkotha
Language Haskell (GHC 7.4.1)
Score 100
Code Size 4525 Byte
Status AC
Exec Time 470 ms
Memory 12508 KB

Judge Result

Set Name Small Large
Score / Max Score 50 / 50 50 / 50
Status
AC × 28
AC × 58
Set Name Test Cases
Small 10-small_random-00, 10-small_random-01, 10-small_random-02, 10-small_random-03, 10-small_random-04, 10-small_random-05, 10-small_random-06, 10-small_random-07, 10-small_random-08, 10-small_random-09, 10-small_random-10, 10-small_random-11, 10-small_random-12, 10-small_random-13, 10-small_random-14, 10-small_random-15, 10-small_random-16, 10-small_random-17, 10-small_random-18, 10-small_random-19, 21-small_path-00, 21-small_path-01, 21-small_path-02, 21-small_path-03, 21-small_path-04, 00-sample-00, 00-sample-01, 00-sample-02
Large 00-sample-00, 00-sample-01, 00-sample-02, 10-small_random-00, 10-small_random-01, 10-small_random-02, 10-small_random-03, 10-small_random-04, 10-small_random-05, 10-small_random-06, 10-small_random-07, 10-small_random-08, 10-small_random-09, 10-small_random-10, 10-small_random-11, 10-small_random-12, 10-small_random-13, 10-small_random-14, 10-small_random-15, 10-small_random-16, 10-small_random-17, 10-small_random-18, 10-small_random-19, 20-small_tree-00, 20-small_tree-01, 20-small_tree-02, 20-small_tree-03, 20-small_tree-04, 21-small_path-00, 21-small_path-01, 21-small_path-02, 21-small_path-03, 21-small_path-04, 30-large_random-00, 30-large_random-01, 30-large_random-02, 30-large_random-03, 30-large_random-04, 30-large_random-05, 30-large_random-06, 30-large_random-07, 30-large_random-08, 30-large_random-09, 40-large_comp-00, 40-large_comp-01, 40-large_comp-02, 40-large_comp-03, 40-large_comp-04, 41-large_tree-00, 41-large_tree-01, 41-large_tree-02, 41-large_tree-03, 41-large_tree-04, 42-large_path-00, 42-large_path-01, 42-large_path-02, 42-large_path-03, 42-large_path-04
Case Name Status Exec Time Memory
00-sample-00 AC 134 ms 1444 KB
00-sample-01 AC 26 ms 1236 KB
00-sample-02 AC 25 ms 1240 KB
10-small_random-00 AC 26 ms 1492 KB
10-small_random-01 AC 27 ms 1744 KB
10-small_random-02 AC 25 ms 1368 KB
10-small_random-03 AC 26 ms 1364 KB
10-small_random-04 AC 28 ms 1732 KB
10-small_random-05 AC 27 ms 1872 KB
10-small_random-06 AC 26 ms 1368 KB
10-small_random-07 AC 25 ms 1448 KB
10-small_random-08 AC 24 ms 1296 KB
10-small_random-09 AC 25 ms 1488 KB
10-small_random-10 AC 26 ms 1492 KB
10-small_random-11 AC 26 ms 1488 KB
10-small_random-12 AC 25 ms 1620 KB
10-small_random-13 AC 27 ms 1304 KB
10-small_random-14 AC 26 ms 1892 KB
10-small_random-15 AC 26 ms 1492 KB
10-small_random-16 AC 25 ms 1872 KB
10-small_random-17 AC 25 ms 1872 KB
10-small_random-18 AC 26 ms 1876 KB
10-small_random-19 AC 27 ms 1944 KB
20-small_tree-00 AC 29 ms 1876 KB
20-small_tree-01 AC 27 ms 1236 KB
20-small_tree-02 AC 30 ms 1880 KB
20-small_tree-03 AC 25 ms 1236 KB
20-small_tree-04 AC 195 ms 3160 KB
21-small_path-00 AC 26 ms 1368 KB
21-small_path-01 AC 28 ms 1364 KB
21-small_path-02 AC 27 ms 1232 KB
21-small_path-03 AC 25 ms 1360 KB
21-small_path-04 AC 27 ms 1620 KB
30-large_random-00 AC 80 ms 7252 KB
30-large_random-01 AC 27 ms 1752 KB
30-large_random-02 AC 34 ms 2648 KB
30-large_random-03 AC 26 ms 1432 KB
30-large_random-04 AC 57 ms 3412 KB
30-large_random-05 AC 26 ms 1496 KB
30-large_random-06 AC 37 ms 2388 KB
30-large_random-07 AC 26 ms 2004 KB
30-large_random-08 AC 470 ms 12364 KB
30-large_random-09 AC 465 ms 12508 KB
40-large_comp-00 AC 26 ms 1316 KB
40-large_comp-01 AC 29 ms 2540 KB
40-large_comp-02 AC 26 ms 2020 KB
40-large_comp-03 AC 38 ms 3412 KB
40-large_comp-04 AC 71 ms 6228 KB
41-large_tree-00 AC 24 ms 1364 KB
41-large_tree-01 AC 30 ms 2132 KB
41-large_tree-02 AC 30 ms 2020 KB
41-large_tree-03 AC 53 ms 2132 KB
41-large_tree-04 AC 191 ms 3288 KB
42-large_path-00 AC 36 ms 1984 KB
42-large_path-01 AC 27 ms 1620 KB
42-large_path-02 AC 26 ms 1936 KB
42-large_path-03 AC 84 ms 2536 KB
42-large_path-04 AC 165 ms 3284 KB