This documentation is automatically generated by online-judge-tools/verification-helper
require "../graph"
module Graph(Edge, Edge2)
# Returns table of color if the graph is bipartite graph, otherwise returns `nil`
def bipartite_graph : Array(Bool)?
color = Array(Bool?).new(size, nil)
queue = Deque.new (0...size).to_a
while v = queue.shift?
c1 = color[v]
c1 = color[v] = true if c1.nil?
graph[v].each do |edge|
if (c2 = color[edge.to]).nil?
color[edge.to] = !c1
queue.unshift edge.to
else
return nil if c1 == c2
end
end
end
color.map(&.not_nil!)
end
end
# require "../graph"
# require "./graph/edge"
struct WeightedEdge(T)
include Comparable(WeightedEdge(T))
property to : Int32, cost : T
def initialize(@to, @cost : T)
end
def <=>(other : WeightedEdge(T))
{cost, to} <=> {other.cost, other.to}
end
def to_s(io) : Nil
io << '(' << to << ", " << cost << ')'
end
def inspect(io) : Nil
io << "->" << to << '(' << cost << ')'
end
end
struct WeightedEdge2(T)
include Comparable(WeightedEdge2(T))
property from : Int32, to : Int32, cost : T
def initialize(@from, @to, @cost : T)
end
def initialize(@from, edge : WeightedEdge(T))
@to, @cost = edge.to, edge.cost
end
def <=>(other : WeightedEdge2(T))
{cost, from, to} <=> {other.cost, other.from, other.to}
end
def reverse : self
WeightedEdge2(T).new(to, from, cost)
end
def sort : self
WeightedEdge2(T).new(*{to, from}.minmax, cost)
end
def to_s(io) : Nil
io << '(' << from << ", " << to << ", " << cost << ')'
end
def inspect(io) : Nil
io << from << "->" << to << '(' << cost << ')'
end
end
struct UnweightedEdge
property to : Int32
def initialize(@to)
end
def initialize(@to, cost)
end
def cost : Int32
1
end
def to_s(io) : Nil
io << to
end
def inspect(io) : Nil
io << "->" << to
end
end
struct UnweightedEdge2
property from : Int32, to : Int32
def initialize(@from, @to)
end
def initialize(@from, @to, cost)
end
def initialize(@from, edge : UnweightedEdge)
@to = edge.to
end
def cost : Int32
1
end
def reverse : self
UnweightedEdge2.new(to, from)
end
def sort : self
UnweightedEdge2.new(*{to, from}.minmax)
end
def to_s(io) : Nil
io << '(' << from << ", " << to << ')'
end
def inspect(io) : Nil
io << from << "->" << to
end
end
module Graph(Edge, Edge2)
include Enumerable(Edge2)
getter graph : Array(Array(Edge))
def initialize(size : Int)
@graph = Array(Array(Edge)).new(size) { [] of Edge }
end
def initialize(size : Int, edges : Enumerable)
initialize(size)
add_edges(edges)
end
# Add *edge*.
abstract def <<(edge : Edge2)
# :ditto:
def <<(edge : Tuple) : self
self << Edge2.new(*edge)
end
def add_edges(edges : Enumerable) : self
edges.each { |edge| self << edge }
self
end
delegate size, :[], to: @graph
# Yields each edge of the graph, ans returns `nil`.
def each(&) : Nil
(0...size).each do |v|
graph[v].each do |edge|
yield Edge2.new(v, edge)
end
end
end
def each_child(vertex : Int, parent, &block) : Nil
graph[vertex].each do |edge|
yield edge if edge.to != parent
end
end
def each_child(vertex : Int, parent)
graph[vertex].each.reject(&.to.== parent)
end
def reverse : self
if self.class.directed?
each_with_object(self.class.new(size)) do |edge, reversed|
reversed << edge.reverse
end
else
dup
end
end
def to_undirected : self
if self.class.directed?
each_with_object(self.class.new(size)) do |edge, graph|
graph << edge << edge.reverse
end
else
dup
end
end
def to_s(io : IO) : Nil
io << '['
join(", ", io) do |edge, io|
edge.inspect io
end
io << ']'
end
def inspect(io : IO) : Nil
io << "[\n"
graph.each do |edges|
io << " " << edges << ",\n"
end
io << ']'
end
end
class DiGraph(T)
include Graph(WeightedEdge(T), WeightedEdge2(T))
def self.weighted?
true
end
def self.directed?
true
end
def initialize(size : Int)
super
end
def initialize(size : Int, edges : Enumerable(WeightedEdge2(T)))
super
end
def initialize(size : Int, edges : Enumerable({Int32, Int32, T}))
super
end
def <<(edge : WeightedEdge2(T)) : self
raise IndexError.new unless 0 <= edge.from < size && 0 <= edge.to < size
@graph[edge.from] << WeightedEdge.new(edge.to, edge.cost)
self
end
end
class UnGraph(T)
include Graph(WeightedEdge(T), WeightedEdge2(T))
def self.weighted?
true
end
def self.directed?
false
end
def initialize(size : Int)
super
end
def initialize(size : Int, edges : Enumerable(WeightedEdge2(T)))
super
end
def initialize(size : Int, edges : Enumerable({Int32, Int32, T}))
super
end
def <<(edge : WeightedEdge2(T)) : self
raise IndexError.new unless 0 <= edge.from < size && 0 <= edge.to < size
@graph[edge.from] << WeightedEdge.new(edge.to, edge.cost)
@graph[edge.to] << WeightedEdge.new(edge.from, edge.cost)
self
end
end
class UnweightedDiGraph
include Graph(UnweightedEdge, UnweightedEdge2)
def self.weighted?
false
end
def self.directed?
true
end
def initialize(size : Int)
super
end
def initialize(size : Int, edges : Enumerable)
super
end
def <<(edge : UnweightedEdge2) : self
raise IndexError.new unless 0 <= edge.from < size && 0 <= edge.to < size
@graph[edge.from] << UnweightedEdge.new(edge.to)
self
end
end
class UnweightedUnGraph
include Graph(UnweightedEdge, UnweightedEdge2)
def self.weighted?
false
end
def self.directed?
false
end
def initialize(size : Int)
super
end
def initialize(size : Int, edges : Enumerable)
super
end
def <<(edge : UnweightedEdge2) : self
raise IndexError.new unless 0 <= edge.from < size && 0 <= edge.to < size
@graph[edge.from] << UnweightedEdge.new(edge.to)
@graph[edge.to] << UnweightedEdge.new(edge.from)
self
end
end
module Graph(Edge, Edge2)
# Returns table of color if the graph is bipartite graph, otherwise returns `nil`
def bipartite_graph : Array(Bool)?
color = Array(Bool?).new(size, nil)
queue = Deque.new (0...size).to_a
while v = queue.shift?
c1 = color[v]
c1 = color[v] = true if c1.nil?
graph[v].each do |edge|
if (c2 = color[edge.to]).nil?
color[edge.to] = !c1
queue.unshift edge.to
else
return nil if c1 == c2
end
end
end
color.map(&.not_nil!)
end
end