blob: aceda76960f5752d50097f7614ab7652ffbff19b [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Package graph contains graph-related utility functions.
package graph
type bipartite struct {
edge map[int][]int
}
// NewBipartite returns a bipartite graph structure.
func NewBipartite() *bipartite {
var g bipartite
g.edge = make(map[int][]int)
return &g
}
// AddEdge adds an edge from x to y. Note that x would be source and y would be sink. Those two number are treated differently even though their number is the same. In other word, AddEdge(1, 1) is not a self-loop but an edge from source #1 to sink #1.
func (g bipartite) AddEdge(x, y int) {
if edges, ok := g.edge[x]; !ok {
g.edge[x] = []int{y}
} else {
g.edge[x] = append(edges, y)
}
}
// matchingHelper returns true if matching for vertex u is possible.
func (g bipartite) matchingHelper(u int, match map[int]int, seen map[int]bool) bool {
for _, dest := range g.edge[u] {
if seen[dest] {
continue
}
seen[dest] = true
if matched, ok := match[dest]; !ok || g.matchingHelper(matched, match, seen) {
match[dest] = u
return true
}
}
return false
}
// MaxMatching returns the max number of matchings in the bipartite graph.
func (g bipartite) MaxMatching() int {
matchMap := make(map[int]int)
count := 0
for src := range g.edge {
if g.matchingHelper(src, matchMap, map[int]bool{}) {
count = count + 1
}
}
return count
}