Past exam of the computer science course of the University of Oxford 2019 Algorithms 1 d Solution 2026-10-25
Separate the forced integer portion from the choice of rounding direction. Put and . Define residual demandsThese are nonnegative integers, since the original row and column sums are integers. Also . Each fractional part satisfies .
Construct a flow network with a vertex for each row and column, source-to-row arcs of flow network edge capacity , row-to-column arcs of flow network edge capacity one exactly where , and column-to-sink arcs of flow network edge capacity . The amounts themselves define a fractional feasible flow of flow value . No flow can exceed , the total source flow network edge capacity. Because all constructed flow network edge capacities are integers, an integral maximum flow also has flow value and saturates every source and sink arc.
Let be its middle-arc flow, taking when that arc is absent. Then , and the required answer isAt an already integral entry no middle arc exists, so that entry stays fixed. At a nonintegral entry the two possibilities are precisely its floor and ceiling. Flow conservation gives and , preserving every original row and column sum.
This is matrix rounding with fixed margins. There are vertices and at most arcs. Exact rational arithmetic computes the floors and residual demands in polynomial time in the encoded input length; the resulting flow network edge capacities are small integers, so there is no need to scale by a potentially large common denominator.
Place an implicit conversion in the companion object and import it into the client scope, so it is available for both an integer argument and an integer receiver:
import scala.language.implicitConversions
class Rational(n0: BigInt, d0: BigInt) {
def this(n: Int, d: Int) = this(BigInt(n), BigInt(d))
require(d0 != 0)
private val g = n0.abs.gcd(d0.abs)
val num: BigInt = (if (d0 < 0) -n0 else n0) / g
val den: BigInt = d0.abs / g
def *(r: Rational): Rational =
new Rational(num*r.num, den*r.den)
override def toString: String =
if (den == 1) num.toString else num.toString + "/" + den.toString
}
object Rational {
implicit def fromInt(n: Int): Rational = new Rational(n,1)
}
import Rational._
val r1 = new Rational(3,7)
val r2 = new Rational(-11,-5)
println(r1*r2)
println(r1*3)
println(7*r1)Normalization gives . The output lines are
33/35, 9/7, 3. For r1*3, the argument is converted; for 7*r1, conversion supplies the receiver's rational multiplication method. BigInt keeps the exact rational arithmetic independent of fixed-width product overflow. Rational arithmetic Created 2026-10-20 Updated 2026-11-05
Exact arithmetic on rational numbers represented by integer numerators and nonzero integer denominators. Common factors can be removed with the greatest common divisor. Exact rational arithmetic avoids rounding error when deciding equality or integrality.