結果

問題 No.1288 yuki collection
ユーザー 草苺奶昔草苺奶昔
提出日時 2023-03-11 20:03:24
言語 Go
(1.22.1)
結果
WA  
実行時間 -
コード長 3,155 bytes
コンパイル時間 12,308 ms
コンパイル使用メモリ 212,100 KB
実行使用メモリ 17,360 KB
最終ジャッジ日時 2023-10-18 10:14:56
合計ジャッジ時間 24,910 ms
ジャッジサーバーID
(参考情報)
judge15 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,348 KB
testcase_01 AC 1 ms
4,348 KB
testcase_02 AC 2 ms
4,348 KB
testcase_03 AC 1 ms
4,348 KB
testcase_04 AC 1 ms
4,348 KB
testcase_05 AC 1 ms
4,348 KB
testcase_06 AC 1 ms
4,348 KB
testcase_07 AC 1 ms
4,348 KB
testcase_08 AC 2 ms
4,348 KB
testcase_09 AC 2 ms
4,348 KB
testcase_10 AC 2 ms
4,348 KB
testcase_11 AC 2 ms
4,348 KB
testcase_12 AC 2 ms
4,348 KB
testcase_13 AC 675 ms
8,852 KB
testcase_14 AC 654 ms
8,856 KB
testcase_15 AC 535 ms
15,180 KB
testcase_16 AC 523 ms
15,116 KB
testcase_17 AC 690 ms
17,224 KB
testcase_18 WA -
testcase_19 AC 713 ms
17,296 KB
testcase_20 AC 701 ms
8,904 KB
testcase_21 AC 537 ms
8,756 KB
testcase_22 AC 527 ms
17,164 KB
testcase_23 AC 603 ms
17,140 KB
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 AC 283 ms
8,848 KB
testcase_28 AC 357 ms
8,804 KB
testcase_29 WA -
testcase_30 AC 14 ms
8,124 KB
testcase_31 AC 19 ms
8,240 KB
testcase_32 AC 21 ms
8,368 KB
testcase_33 AC 135 ms
8,352 KB
testcase_34 AC 175 ms
8,320 KB
testcase_35 AC 166 ms
8,340 KB
testcase_36 AC 174 ms
8,380 KB
testcase_37 AC 188 ms
12,644 KB
testcase_38 AC 135 ms
8,360 KB
testcase_39 AC 136 ms
8,352 KB
testcase_40 AC 5 ms
5,668 KB
testcase_41 AC 1 ms
4,348 KB
testcase_42 AC 2 ms
4,348 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

package main

import (
	"bufio"
	"fmt"
	"os"
)

const INF int = 1e18

func removeYuki(s string, scores []int) int {
	n := len(s)
	A := func(i int) int { return i }
	B := func(i int) int { return n + 1 + i }
	C := func(i int) int { return 2*(n+1) + i }
	D := func(i int) int { return 3*(n+1) + i }
	E := func(i int) int { return 4*(n+1) + i }
	mcmf := NewMinCostFlow(5*n+5, A(0), E(n))
	for i := 0; i < n; i++ {
		mcmf.AddEdge(A(i), A(i+1), n, 0)
		mcmf.AddEdge(B(i), B(i+1), n, 0)
		mcmf.AddEdge(C(i), C(i+1), n, 0)
		mcmf.AddEdge(D(i), D(i+1), n, 0)
		mcmf.AddEdge(E(i), E(i+1), n, 0)
	}
	for i := 0; i < n; i++ {
		if s[i] == 'y' {
			mcmf.AddEdge(A(i), B(i+1), 1, -scores[i])
		}
		if s[i] == 'u' {
			mcmf.AddEdge(B(i), C(i+1), 1, -scores[i])
		}
		if s[i] == 'k' {
			mcmf.AddEdge(C(i), D(i+1), 1, -scores[i])
		}
		if s[i] == 'i' {
			mcmf.AddEdge(D(i), E(i+1), 1, -scores[i])
		}
	}

	_, maxCost := mcmf.Work()
	return -maxCost
}

type MinCostFlow struct {
	AddEdge func(from, to, cap, cost int)
	Work    func() (maxFlow int, minCost int)
}

func NewMinCostFlow(n, start, end int) *MinCostFlow {
	type neighbor struct {
		to   int
		rid  int // rid 为反向边在邻接表中的下标
		cap  int // 边的残量
		cost int
		eid  int // -1表示是反向边
	}

	graph := make([][]neighbor, n)
	ei := 0
	addEdge := func(from, to, cap, cost, eid int) {
		graph[from] = append(graph[from], neighbor{to, len(graph[to]), cap, cost, eid})
		graph[to] = append(graph[to], neighbor{from, len(graph[from]) - 1, 0, -cost, -1})
	}

	dist := make([]int, len(graph))
	type vi struct{ v, i int }
	pre := make([]vi, len(graph))
	spfa := func() bool {
		for i := range dist {
			dist[i] = INF
		}
		dist[start] = 0
		inQueue := make([]bool, len(graph))
		inQueue[start] = true
		queue := []int{start}
		for len(queue) > 0 {
			cur := queue[0]
			queue = queue[1:]
			inQueue[cur] = false
			for i, edge := range graph[cur] {
				if edge.cap == 0 {
					continue
				}
				next := edge.to
				if cand := dist[cur] + int(edge.cost); cand < dist[next] {
					dist[next] = cand
					pre[next] = vi{cur, i}
					if !inQueue[next] {
						queue = append(queue, next)
						inQueue[next] = true
					}
				}
			}
		}
		return dist[end] < INF
	}

	ek := func() (maxFlow int, minCost int) {
		for spfa() {
			// 沿 st-end 的最短路尽量增广
			flow := INF
			for cur := end; cur != start; {
				p := pre[cur]
				if c := graph[p.v][p.i].cap; c < flow {
					flow = c
				}
				cur = p.v
			}
			for cur := end; cur != start; {
				p := pre[cur]
				edge := &graph[p.v][p.i]
				edge.cap -= flow
				graph[cur][edge.rid].cap += flow
				cur = p.v
			}
			maxFlow += flow
			minCost += dist[end] * flow
		}
		return
	}

	AddEdge := func(from, to, cap, cost int) {
		addEdge(from, to, cap, cost, ei)
		ei++
	}

	return &MinCostFlow{
		AddEdge: AddEdge,
		Work:    ek,
	}
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n int
	fmt.Fscan(in, &n)
	var s string
	fmt.Fscan(in, &s)
	scores := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(in, &scores[i])
	}
	fmt.Fprintln(out, removeYuki(s, scores))
}
0