提出 #47961856


ソースコード 拡げる

import scala.collection.mutable
import scala.reflect.ClassTag

inline def rep(n: Int, f: => Unit): Unit = { var c = 0; while (c < n) { f; c += 1 } }
inline def rep(n: Int, f: Int => Unit): Unit = { var c = 0; while (c < n) { f(c); c += 1 } }

final class InputReader() {
  import scala.util.Using

  private var i = 0
  private val lines = Using(io.Source.fromFile("/dev/stdin"))(_.getLines().toArray).get
  private var tokenizer: java.util.StringTokenizer = null

  private def next(): String = {
    while (tokenizer == null || !tokenizer.hasMoreTokens) {
      tokenizer = java.util.StringTokenizer(lines(i))
      lines(i) = null
      i += 1
    }
    tokenizer.nextToken()
  }

  inline def nextStr(): String = next()
  inline def nextInt(): Int = java.lang.Integer.parseInt(next()) // inlined `String.toInt()`
  inline def nextLong(): Long = java.lang.Long.parseLong(next()) // inlined `String.toLong()`
}

object Main {

  def main(_args: Array[String]): Unit = {
    val in = new InputReader()
    val out = new java.io.PrintWriter(System.out)

    val n = in.nextInt()
    val m = in.nextInt()
    val g = SccGraph(n)
    (0 until m).foreach(_ => {
      val a = in.nextInt()
      val b = in.nextInt()

      g.addEdge(a, b)
    })

    try {
      val ans = g.scc()

      out.println(ans.size)
      for (vs <- ans) {
        out.print(s"${vs.size} ")
        out.println(vs.mkString(" "))
      }
    } catch {
      case e: Throwable =>
        e.printStackTrace(out)
    } finally {
      out.flush()
    }
  }

}

package internal {
  private[internal] case class Edge(to: Int)

  private[internal] case class Csr[E] private (start: Array[Int], eList: Array[E])
  private[internal] object Csr {
    def apply[E: ClassTag](n: Int, edges: collection.Seq[(Int, E)]): Csr[E] = {
      val csr = Csr(new Array[Int](n+1), new Array[E](edges.size))
      for ((from, _) <- edges) {
        csr.start(from + 1) += 1
      }
      (1 to n).foreach(i => {
        csr.start(i) += csr.start(i - 1)
      })
      val counter = csr.start.clone()
      for ((from, edge) <- edges) {
        csr.eList(counter(from)) = edge
        counter(from) += 1
      }
      csr
    }
  }

  /**
   * Reference:
   * R. Tarjan,
   * Depth-First Search and Linear Graph Algorithms
   */
  case class SccGraph(private val n: Int) {
    private val edges: mutable.Buffer[(Int, Edge)] = mutable.ListBuffer.empty

    def numVertices: Int = n

    def addEdge(from: Int, to: Int): Unit = {
      edges += ((from, Edge(to)))
    }

    private var g: Csr[Edge] = null
    private var now_ord = 0
    private var group_num = 0
    private var visited: mutable.Stack[Int] = null
    private var ord: Array[Int] = null
    private var low: Array[Int] = null
    private var ids: Array[Int] = null

    private def dfs(v: Int): Unit = {
      low(v) = now_ord
      ord(v) = now_ord
      now_ord += 1
      visited.push(v)
      (g.start(v) until g.start(v + 1)).foreach(i => {
        val to = g.eList(i).to
        if (ord(to) == -1) {
          dfs(to)
          low(v) = low(v).min(low(to))
        } else {
          low(v) = low(v).min(ord(to))
        }
      })
      if (low(v) == ord(v)) {
        while {
          // do
          val u = visited.pop()
          ord(u) = n
          ids(u) = group_num

          // while
          u != v
        } do {}
        group_num += 1
      }
    }

    /**
     * @return pair of (# of scc, scc id)
     */
    def sccIds(): (Int, Array[Int]) = {
      g = Csr(n, edges)
      now_ord = 0
      group_num = 0
      visited = new mutable.Stack[Int](n)
      ord = Array.fill(n)(-1)
      low = new Array[Int](n)
      ids = new Array[Int](n)

      (0 until n).foreach(i => {
        if (ord(i) == -1) { dfs(i) }
      })
      (0 until n).foreach(i => {
        ids(i) = group_num - 1 - ids(i)
      })

      (group_num, ids)
    }

    def scc(): collection.Seq[collection.Seq[Int]] = {
      val (group_nums, ids) = sccIds()
      val counts = new Array[Int](group_nums)
      ids.foreach(x => { counts(x) += 1 })
      val groups = new mutable.ArrayBuffer[mutable.Buffer[Int]](n)
      (0 until group_nums).foreach(i => {
        groups += new mutable.ArrayBuffer[Int](counts(i))
      })
      (0 until n).foreach(i => {
        groups(ids(i)) += i
      })

      groups
    }
  }
}

case class SccGraph(private val internal: _root_.internal.SccGraph) {

  def addEdge(from: Int, to: Int): Unit = {
    val n = internal.numVertices
    assert(0 <= from && from < n)
    assert(0 <= to && to < n)
    internal.addEdge(from, to)
  }

  def scc(): collection.Seq[collection.Seq[Int]] = {
    internal.scc()
  }

}

object SccGraph {
  def apply(n: Int): SccGraph = {
    new SccGraph(internal.SccGraph(n))
  }
}

提出情報

提出日時
問題 G - SCC
ユーザ harry0000
言語 Scala (Dotty 3.3.0)
得点 0
コード長 4947 Byte
結果 WA
実行時間 1787 ms
メモリ 213328 KiB

コンパイルエラー

Starting compilation server
Compiling project (Scala 3.3.0, JVM)
Compiled project (Scala 3.3.0, JVM)
Wrote /judge/Main, run it with
  ./Main

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 0 / 100
結果
AC × 1
AC × 10
WA × 1
セット名 テストケース
Sample example_00
All example_00, max_random_00, max_random_01, max_random_02, max_random_03, max_random_04, random_00, random_01, random_02, random_03, random_04
ケース名 結果 実行時間 メモリ
example_00 AC 278 ms 57012 KiB
max_random_00 AC 1603 ms 197916 KiB
max_random_01 AC 1671 ms 211592 KiB
max_random_02 AC 1671 ms 213328 KiB
max_random_03 AC 1639 ms 199864 KiB
max_random_04 AC 1787 ms 210216 KiB
random_00 AC 1468 ms 170432 KiB
random_01 AC 1425 ms 178224 KiB
random_02 WA 705 ms 114776 KiB
random_03 AC 1078 ms 125732 KiB
random_04 AC 1093 ms 115048 KiB