← Home
For problem statement at 1000-1999/1100-1199/1180-1189/1184/problemB3.txt this is a correct solution, but verifier at 1000-1999/1100-1199/1180-1189/1184/verifierB3.go ends with test 12 failed
input:
7 2
5 6
6 3
4 5 2
2 17 7 9
4 6 9 4
2 14 9 3
1 4 9 10
3 13 20
3 5 11
1 1 8
7 4 22
2 1 0
4 1
1 3

expected: 40
got: 0

exit status 1 can you fix the verifier? package main

import (
	"io"
	"os"
	"sort"
	"strconv"
)

type Base struct {
	d int
	g int64
}

type Edge struct {
	to  int
	rev int
	cap int64
}

type Dinic struct {
	g     [][]Edge
	level []int
	it    []int
}

func NewDinic(n int) *Dinic {
	return &Dinic{
		g:     make([][]Edge, n),
		level: make([]int, n),
		it:    make([]int, n),
	}
}

func (d *Dinic) AddEdge(fr, to int, cap int64) {
	fwd := Edge{to: to, rev: len(d.g[to]), cap: cap}
	rev := Edge{to: fr, rev: len(d.g[fr]), cap: 0}
	d.g[fr] = append(d.g[fr], fwd)
	d.g[to] = append(d.g[to], rev)
}

func (d *Dinic) bfs(s, t int) bool {
	for i := range d.level {
		d.level[i] = -1
	}
	q := make([]int, 0, len(d.g))
	d.level[s] = 0
	q = append(q, s)
	for h := 0; h < len(q); h++ {
		v := q[h]
		for _, e := range d.g[v] {
			if e.cap > 0 && d.level[e.to] < 0 {
				d.level[e.to] = d.level[v] + 1
				q = append(q, e.to)
			}
		}
	}
	return d.level[t] >= 0
}

func min64(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func (d *Dinic) dfs(v, t int, f int64) int64 {
	if v == t {
		return f
	}
	for ; d.it[v] < len(d.g[v]); d.it[v]++ {
		i := d.it[v]
		e := &d.g[v][i]
		if e.cap > 0 && d.level[e.to] == d.level[v]+1 {
			ret := d.dfs(e.to, t, min64(f, e.cap))
			if ret > 0 {
				e.cap -= ret
				re := &d.g[e.to][e.rev]
				re.cap += ret
				return ret
			}
		}
	}
	return 0
}

func (d *Dinic) MaxFlow(s, t int) int64 {
	var flow int64
	const INF int64 = 1 << 60
	for d.bfs(s, t) {
		for i := range d.it {
			d.it[i] = 0
		}
		for {
			f := d.dfs(s, t, INF)
			if f == 0 {
				break
			}
			flow += f
		}
	}
	return flow
}

func upperBound(a []int, x int) int {
	l, r := 0, len(a)
	for l < r {
		m := (l + r) >> 1
		if a[m] <= x {
			l = m + 1
		} else {
			r = m
		}
	}
	return l
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	pos := 0
	nextInt := func() int {
		for pos < len(data) && (data[pos] < '0' || data[pos] > '9') {
			pos++
		}
		v := 0
		for pos < len(data) && data[pos] >= '0' && data[pos] <= '9' {
			v = v*10 + int(data[pos]-'0')
			pos++
		}
		return v
	}

	n := nextInt()
	m := nextInt()

	const INFINT = 1000001000
	dist := make([][]int, n)
	for i := 0; i < n; i++ {
		dist[i] = make([]int, n)
		for j := 0; j < n; j++ {
			dist[i][j] = INFINT
		}
		dist[i][i] = 0
	}

	for i := 0; i < m; i++ {
		u := nextInt() - 1
		v := nextInt() - 1
		dist[u][v] = 1
		dist[v][u] = 1
	}

	for k := 0; k < n; k++ {
		rowk := dist[k]
		for i := 0; i < n; i++ {
			dik := dist[i][k]
			if dik == INFINT {
				continue
			}
			rowi := dist[i]
			for j := 0; j < n; j++ {
				nd := dik + rowk[j]
				if nd < rowi[j] {
					rowi[j] = nd
				}
			}
		}
	}

	s := nextInt()
	b := nextInt()
	kdep := nextInt()

	shipLoc := make([]int, s)
	shipAtk := make([]int, s)
	shipFuel := make([]int, s)
	shipPrice := make([]int64, s)

	for i := 0; i < s; i++ {
		shipLoc[i] = nextInt() - 1
		shipAtk[i] = nextInt()
		shipFuel[i] = nextInt()
		shipPrice[i] = int64(nextInt())
	}

	baseGroups := make([][]Base, n)
	for i := 0; i < b; i++ {
		x := nextInt() - 1
		d := nextInt()
		g := int64(nextInt())
		baseGroups[x] = append(baseGroups[x], Base{d: d, g: g})
	}

	defsByNode := make([][]int, n)
	prefByNode := make([][]int64, n)

	for i := 0; i < n; i++ {
		g := baseGroups[i]
		if len(g) == 0 {
			continue
		}
		sort.Slice(g, func(a, b int) bool {
			return g[a].d < g[b].d
		})
		defs := make([]int, len(g))
		pref := make([]int64, len(g))
		var mx int64 = -1
		for j := 0; j < len(g); j++ {
			defs[j] = g[j].d
			if g[j].g > mx {
				mx = g[j].g
			}
			pref[j] = mx
		}
		defsByNode[i] = defs
		prefByNode[i] = pref
	}

	values := make([]int64, s)
	available := make([]bool, s)

	for i := 0; i < s; i++ {
		best := int64(-1)
		x := shipLoc[i]
		atk := shipAtk[i]
		fuel := shipFuel[i]
		row := dist[x]
		for y := 0; y < n; y++ {
			if row[y] > fuel {
				continue
			}
			defs := defsByNode[y]
			if len(defs) == 0 {
				continue
			}
			p := upperBound(defs, atk) - 1
			if p >= 0 {
				g := prefByNode[y][p]
				if g > best {
					best = g
				}
			}
		}
		if best >= 0 {
			available[i] = true
			values[i] = best - shipPrice[i]
		}
	}

	depA := make([]int, kdep)
	depB := make([]int, kdep)
	involved := make([]bool, s)

	for i := 0; i < kdep; i++ {
		a := nextInt() - 1
		bb := nextInt() - 1
		depA[i] = a
		depB[i] = bb
		involved[a] = true
		involved[bb] = true
	}

	idMap := make([]int, s)
	for i := 0; i < s; i++ {
		idMap[i] = -1
	}

	involvedList := make([]int, 0)
	var answer int64

	for i := 0; i < s; i++ {
		if involved[i] {
			idMap[i] = len(involvedList)
			involvedList = append(involvedList, i)
		} else if available[i] && values[i] > 0 {
			answer += values[i]
		}
	}

	cnt := len(involvedList)
	if cnt > 0 {
		src := cnt
		sink := cnt + 1
		din := NewDinic(cnt + 2)
		const INF int64 = 1 << 60
		var totalPos int64

		for id, ship := range involvedList {
			if available[ship] {
				w := values[ship]
				if w > 0 {
					din.AddEdge(src, id, w)
					totalPos += w
				} else if w < 0 {
					din.AddEdge(id, sink, -w)
				}
			}
			if !available[ship] {
				din.AddEdge(id, sink, INF)
			}
		}

		for i := 0; i < kdep; i++ {
			u := idMap[depA[i]]
			v := idMap[depB[i]]
			din.AddEdge(u, v, INF)
		}

		answer += totalPos - din.MaxFlow(src, sink)
	}

	os.Stdout.WriteString(strconv.FormatInt(answer, 10))
}