← Home
For problem statement at 0-999/200-299/260-269/260/problemD.txt this is a correct solution, but verifier at 0-999/200-299/260-269/260/verifierD.go ends with All tests passed can you fix the verifier? package main

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

type Edge struct {
	u int
	v int
	w int64
}

type DSU struct {
	p  []int
	sz []int
}

func NewDSU(n int) *DSU {
	p := make([]int, n)
	sz := make([]int, n)
	for i := 0; i < n; i++ {
		p[i] = i
		sz[i] = 1
	}
	return &DSU{p: p, sz: sz}
}

func (d *DSU) Find(x int) int {
	for d.p[x] != x {
		d.p[x] = d.p[d.p[x]]
		x = d.p[x]
	}
	return x
}

func (d *DSU) Union(a, b int) bool {
	ra := d.Find(a)
	rb := d.Find(b)
	if ra == rb {
		return false
	}
	if d.sz[ra] < d.sz[rb] {
		ra, rb = rb, ra
	}
	d.p[rb] = ra
	d.sz[ra] += d.sz[rb]
	return true
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	idx := 0
	nextInt := func() int64 {
		n := len(data)
		for idx < n && data[idx] <= ' ' {
			idx++
		}
		sign := int64(1)
		if idx < n && data[idx] == '-' {
			sign = -1
			idx++
		}
		var val int64
		for idx < n && data[idx] > ' ' {
			val = val*10 + int64(data[idx]-'0')
			idx++
		}
		return val * sign
	}

	n := int(nextInt())
	color := make([]int, n)

	whiteAll := make([]int, 0)
	blackAll := make([]int, 0)

	whiteIDs := make([]int, 0)
	blackIDs := make([]int, 0)
	whiteRem := make([]int64, 0)
	blackRem := make([]int64, 0)

	for i := 0; i < n; i++ {
		c := int(nextInt())
		s := nextInt()
		color[i] = c
		if c == 0 {
			whiteAll = append(whiteAll, i)
			if s > 0 {
				whiteIDs = append(whiteIDs, i)
				whiteRem = append(whiteRem, s)
			}
		} else {
			blackAll = append(blackAll, i)
			if s > 0 {
				blackIDs = append(blackIDs, i)
				blackRem = append(blackRem, s)
			}
		}
	}

	edges := make([]Edge, 0, n-1)
	dsu := NewDSU(n)

	i, j := 0, 0
	for i < len(whiteIDs) && j < len(blackIDs) {
		x := whiteRem[i]
		if blackRem[j] < x {
			x = blackRem[j]
		}
		u := whiteIDs[i]
		v := blackIDs[j]
		edges = append(edges, Edge{u: u, v: v, w: x})
		dsu.Union(u, v)
		whiteRem[i] -= x
		blackRem[j] -= x
		if whiteRem[i] == 0 {
			i++
		}
		if blackRem[j] == 0 {
			j++
		}
	}

	repW := make([]int, n)
	repB := make([]int, n)
	used := make([]bool, n)
	for k := 0; k < n; k++ {
		repW[k] = -1
		repB[k] = -1
	}

	roots := make([]int, 0)
	for v := 0; v < n; v++ {
		r := dsu.Find(v)
		if !used[r] {
			used[r] = true
			roots = append(roots, r)
		}
		if color[v] == 0 {
			if repW[r] == -1 {
				repW[r] = v
			}
		} else {
			if repB[r] == -1 {
				repB[r] = v
			}
		}
	}

	root := -1
	rootWhite := -1
	rootBlack := -1
	for _, r := range roots {
		if repW[r] != -1 && repB[r] != -1 {
			root = r
			rootWhite = repW[r]
			rootBlack = repB[r]
			break
		}
	}

	if root == -1 {
		w0 := whiteAll[0]
		b0 := blackAll[0]
		for _, b := range blackAll {
			edges = append(edges, Edge{u: w0, v: b, w: 0})
		}
		for _, w := range whiteAll {
			if w != w0 {
				edges = append(edges, Edge{u: w, v: b0, w: 0})
			}
		}
	} else {
		for _, r := range roots {
			if r == root {
				continue
			}
			if repW[r] != -1 {
				edges = append(edges, Edge{u: repW[r], v: rootBlack, w: 0})
			} else {
				edges = append(edges, Edge{u: rootWhite, v: repB[r], w: 0})
			}
		}
	}

	out := make([]byte, 0, (n-1)*24)
	for _, e := range edges {
		out = strconv.AppendInt(out, int64(e.u+1), 10)
		out = append(out, ' ')
		out = strconv.AppendInt(out, int64(e.v+1), 10)
		out = append(out, ' ')
		out = strconv.AppendInt(out, e.w, 10)
		out = append(out, '\n')
	}
	os.Stdout.Write(out)
}