For problem statement at 1000-1999/1700-1799/1770-1779/1773/problemJ.txt this is a correct solution, but verifier at 1000-1999/1700-1799/1770-1779/1773/verifierJ.go ends with All 25 tests passed. can you fix the verifier? package main
import (
"io"
"os"
"strconv"
)
type Edge struct {
u, v int
x int64
}
type Block struct {
edges []int
treeEdges []int
}
type Pair struct {
to, eid int
}
type Rel struct {
to int
nt, tr int
}
type Op struct {
coef int64
tr, nt int
}
var (
n, m int
mod int64
edges []Edge
adj [][]int
tin []int
low []int
timer int
estack []int
comps [][]int
)
func dfs(v, pe int) {
timer++
tin[v] = timer
low[v] = timer
for _, eid := range adj[v] {
if eid == pe {
continue
}
e := edges[eid]
to := e.u
if to == v {
to = e.v
}
if tin[to] == 0 {
estack = append(estack, eid)
dfs(to, eid)
if low[to] < low[v] {
low[v] = low[to]
}
if low[to] >= tin[v] {
comp := make([]int, 0)
for {
last := estack[len(estack)-1]
estack = estack[:len(estack)-1]
comp = append(comp, last)
if last == eid {
break
}
}
comps = append(comps, comp)
}
} else if tin[to] < tin[v] {
estack = append(estack, eid)
if tin[to] < low[v] {
low[v] = tin[to]
}
}
}
}
func find(par []int, x int) int {
for par[x] != x {
par[x] = par[par[x]]
x = par[x]
}
return x
}
func powMod(a, e, mod int64) int64 {
res := int64(1)
for e > 0 {
if e&1 == 1 {
res = res * a % mod
}
a = a * a % mod
e >>= 1
}
return res
}
func main() {
data, _ := io.ReadAll(os.Stdin)
idx := 0
nextInt := func() int64 {
for idx < len(data) && data[idx] <= ' ' {
idx++
}
sign := int64(1)
if idx < len(data) && data[idx] == '-' {
sign = -1
idx++
}
var val int64
for idx < len(data) && data[idx] > ' ' {
val = val*10 + int64(data[idx]-'0')
idx++
}
return val * sign
}
n = int(nextInt())
m = int(nextInt())
mod = nextInt()
edges = make([]Edge, m)
adj = make([][]int, n)
for i := 0; i < m; i++ {
u := int(nextInt()) - 1
v := int(nextInt()) - 1
x := nextInt() % mod
edges[i] = Edge{u, v, x}
adj[u] = append(adj[u], i)
adj[v] = append(adj[v], i)
}
tin = make([]int, n)
low = make([]int, n)
for i := 0; i < n; i++ {
if tin[i] == 0 {
dfs(i, -1)
}
}
blocks := make([]Block, len(comps))
inBase := make([]bool, m)
baseTree := make([]int, 0, n-1)
markV := make([]int, n)
markStamp := 0
ufPar := make([]int, n)
ufSz := make([]int, n)
for bi, comp := range comps {
blocks[bi].edges = comp
markStamp++
verts := make([]int, 0)
for _, eid := range comp {
u, v := edges[eid].u, edges[eid].v
if markV[u] != markStamp {
markV[u] = markStamp
verts = append(verts, u)
}
if markV[v] != markStamp {
markV[v] = markStamp
verts = append(verts, v)
}
}
for _, v := range verts {
ufPar[v] = v
ufSz[v] = 1
}
for _, eid := range comp {
u, v := edges[eid].u, edges[eid].v
ru := find(ufPar, u)
rv := find(ufPar, v)
if ru != rv {
if ufSz[ru] < ufSz[rv] {
ru, rv = rv, ru
}
ufPar[rv] = ru
ufSz[ru] += ufSz[rv]
blocks[bi].treeEdges = append(blocks[bi].treeEdges, eid)
inBase[eid] = true
baseTree = append(baseTree, eid)
}
}
}
if len(baseTree) != n-1 {
os.Stdout.Write([]byte("-1\n"))
return
}
possible := true
alphaKnown := false
alpha := int64(0)
for _, block := range blocks {
s := int64(0)
for _, eid := range block.edges {
s += edges[eid].x
if s >= mod {
s %= mod
}
}
s %= mod
r := int64(len(block.treeEdges)) % mod
if r != 0 {
cand := s * powMod(r, mod-2, mod) % mod
if !alphaKnown {
alphaKnown = true
alpha = cand
} else if alpha != cand {
possible = false
break
}
} else if s != 0 {
possible = false
break
}
}
if !possible {
os.Stdout.Write([]byte("-1\n"))
return
}
if !alphaKnown {
alpha = 0
}
for _, block := range blocks {
s := int64(0)
for _, eid := range block.edges {
s += edges[eid].x
if s >= mod {
s %= mod
}
}
s %= mod
r := int64(len(block.treeEdges)) % mod
if s != alpha*r%mod {
possible = false
break
}
}
if !possible {
os.Stdout.Write([]byte("-1\n"))
return
}
baseCoef := alpha
swapOps := make([]Op, 0)
visV := make([]int, n)
parentV := make([]int, n)
parentE := make([]int, n)
bfsStamp := 0
for _, block := range blocks {
if len(block.edges) <= 1 {
continue
}
k := len(block.edges)
idxMap := make(map[int]int, k)
for i, eid := range block.edges {
idxMap[eid] = i
}
treeAdj := make([][]Pair, n)
for _, eid := range block.treeEdges {
u, v := edges[eid].u, edges[eid].v
treeAdj[u] = append(treeAdj[u], Pair{v, eid})
treeAdj[v] = append(treeAdj[v], Pair{u, eid})
}
aux := make([][]Rel, k)
for _, f := range block.edges {
if inBase[f] {
continue
}
u, v := edges[f].u, edges[f].v
bfsStamp++
q := make([]int, 1, len(block.treeEdges)+1)
q[0] = u
visV[u] = bfsStamp
parentV[u] = -1
for head := 0; head < len(q) && visV[v] != bfsStamp; head++ {
cur := q[head]
for _, pr := range treeAdj[cur] {
to := pr.to
if visV[to] == bfsStamp {
continue
}
visV[to] = bfsStamp
parentV[to] = cur
parentE[to] = pr.eid
q = append(q, to)
}
}
if visV[v] != bfsStamp {
possible = false
break
}
a := idxMap[f]
for cur := v; cur != u; cur = parentV[cur] {
e := parentE[cur]
b := idxMap[e]
aux[a] = append(aux[a], Rel{b, f, e})
aux[b] = append(aux[b], Rel{a, f, e})
}
}
if !possible {
break
}
par := make([]int, k)
parNT := make([]int, k)
parTR := make([]int, k)
visE := make([]bool, k)
order := make([]int, 0, k)
q2 := make([]int, 1, k)
q2[0] = 0
visE[0] = true
par[0] = -1
for head := 0; head < len(q2); head++ {
u := q2[head]
order = append(order, u)
for _, rel := range aux[u] {
if visE[rel.to] {
continue
}
visE[rel.to] = true
par[rel.to] = u
parNT[rel.to] = rel.nt
parTR[rel.to] = rel.tr
q2 = append(q2, rel.to)
}
}
if len(order) != k {
possible = false
break
}
w := make([]int64, k)
for i, eid := range block.edges {
val := edges[eid].x
if inBase[eid] {
val -= alpha
val %= mod
if val < 0 {
val += mod
}
}
w[i] = val
}
for t := len(order) - 1; t >= 1; t-- {
uidx := order[t]
c := w[uidx]
pidx := par[uidx]
if c != 0 {
nt := parNT[uidx]
tr := parTR[uidx]
ueid := block.edges[uidx]
peid := block.edges[pidx]
var s int64
if ueid == nt && peid == tr {
s = c
} else if ueid == tr && peid == nt {
s = mod - c
if s == mod {
s = 0
}
} else {
possible = false
break
}
if s != 0 {
swapOps = append(swapOps, Op{s, tr, nt})
baseCoef -= s
baseCoef %= mod
if baseCoef < 0 {
baseCoef += mod
}
}
w[pidx] += c
if w[pidx] >= mod {
w[pidx] -= mod
}
}
}
if !possible {
break
}
if w[order[0]]%mod != 0 {
possible = false
break
}
}
if !possible {
os.Stdout.Write([]byte("-1\n"))
return
}
posInBase := make([]int, m)
for i := 0; i < m; i++ {
posInBase[i] = -1
}
for i, eid := range baseTree {
posInBase[eid] = i
}
allOps := make([]Op, 0, len(swapOps)+1)
if baseCoef != 0 {
allOps = append(allOps, Op{baseCoef, -1, -1})
}
allOps = append(allOps, swapOps...)
out := make([]byte, 0, 1<<20)
out = strconv.AppendInt(out, int64(len(allOps)), 10)
out = append(out, '\n')
for _, op := range allOps {
out = strconv.AppendInt(out, op.coef, 10)
pos := -1
if op.tr != -1 {
pos = posInBase[op.tr]
}
for i, eid := range baseTree {
out = append(out, ' ')
id := eid
if i == pos {
id = op.nt
}
out = strconv.AppendInt(out, int64(id+1), 10)
}
out = append(out, '\n')
}
os.Stdout.Write(out)
}