結果

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

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,348 KB
testcase_01 AC 1 ms
4,348 KB
testcase_02 AC 1 ms
4,348 KB
testcase_03 AC 2 ms
4,348 KB
testcase_04 AC 2 ms
4,348 KB
testcase_05 AC 1 ms
4,348 KB
testcase_06 AC 2 ms
4,348 KB
testcase_07 AC 1 ms
4,348 KB
testcase_08 AC 3 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 710 ms
17,284 KB
testcase_14 AC 680 ms
8,884 KB
testcase_15 AC 551 ms
8,860 KB
testcase_16 AC 543 ms
8,848 KB
testcase_17 AC 711 ms
17,288 KB
testcase_18 AC 760 ms
17,292 KB
testcase_19 AC 719 ms
8,788 KB
testcase_20 AC 733 ms
17,292 KB
testcase_21 AC 555 ms
17,216 KB
testcase_22 AC 548 ms
8,792 KB
testcase_23 AC 615 ms
15,140 KB
testcase_24 AC 716 ms
8,904 KB
testcase_25 AC 724 ms
8,956 KB
testcase_26 AC 763 ms
8,868 KB
testcase_27 AC 282 ms
8,796 KB
testcase_28 AC 361 ms
8,808 KB
testcase_29 AC 356 ms
8,856 KB
testcase_30 AC 14 ms
8,128 KB
testcase_31 AC 19 ms
8,248 KB
testcase_32 AC 21 ms
8,372 KB
testcase_33 AC 138 ms
8,384 KB
testcase_34 AC 177 ms
8,352 KB
testcase_35 AC 165 ms
8,336 KB
testcase_36 AC 172 ms
8,412 KB
testcase_37 AC 184 ms
8,472 KB
testcase_38 AC 137 ms
8,392 KB
testcase_39 AC 134 ms
8,380 KB
testcase_40 AC 5 ms
5,668 KB
testcase_41 AC 1 ms
4,348 KB
testcase_42 AC 1 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])
		} else if s[i] == 'u' {
			mcmf.AddEdge(B(i), C(i+1), 1, -scores[i])
		} else if s[i] == 'k' {
			mcmf.AddEdge(C(i), D(i+1), 1, -scores[i])
		} else if s[i] == 'i' {
			mcmf.AddEdge(D(i), E(i+1), 1, -scores[i])
		}
	}

	slopes := mcmf.Work()
	res := 0
	for _, slope := range slopes {
		res = max(res, -slope[1])
	}
	return res
}
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

type MinCostFlow struct {
	AddEdge func(from, to, cap, cost int)
	Work    func() [][2]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() (slopes [][2]int) {
		maxFlow, minCost := 0, 0
		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
			slopes = append(slopes, [2]int{maxFlow, minCost})
		}
		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