結果
| 問題 |
No.161 制限ジャンケン
|
| コンテスト | |
| ユーザー |
maspy
|
| 提出日時 | 2020-01-29 22:19:14 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
AC
|
| 実行時間 | 34 ms / 5,000 ms |
| コード長 | 2,914 bytes |
| コンパイル時間 | 164 ms |
| コンパイル使用メモリ | 12,672 KB |
| 実行使用メモリ | 10,880 KB |
| 最終ジャッジ日時 | 2024-09-16 02:53:04 |
| 合計ジャッジ時間 | 1,590 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 16 |
ソースコード
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
from heapq import heappop, heappush
me = tuple(map(int,readline().split()))
S = read().rstrip().decode()
op = tuple(S.count(x) for x in 'GCP')
class MinCostFlow:
"""
最小費用流。負辺がないと仮定して、BellmanFordを省略している。
"""
def __init__(self, N, source, sink):
self.N = N
self.G = [[] for _ in range(N)]
self.source = source
self.sink = sink
def add_edge(self, fr, to, cap, cost):
n1 = len(self.G[fr])
n2 = len(self.G[to])
self.G[fr].append([to, cap, cost, n2])
self.G[to].append([fr, 0, -cost, n1])
def min_cost(self, flow, negative_edge = False):
if negative_edge:
raise ValueError
N = self.N; G = self.G; source = self.source; sink = self.sink
INF = 10 ** 18
prev_v = [0] * N; prev_e = [0] * N # 経路復元用
H = [0] * N # potential
mincost=0
while flow:
dist=[INF] * N
dist[source]=0
q = [source]
mask = (1 << 20) - 1
while q:
x = heappop(q)
dv = (x >> 20); v = x & mask
if dist[v] < dv:
continue
if v == sink:
break
for i,(w,cap,cost,rev) in enumerate(G[v]):
dw = dist[v] + cost + H[v] - H[w]
if (not cap) or (dist[w] <= dw):
continue
dist[w] = dw
prev_v[w] = v; prev_e[w] = i
heappush(q, (dw << 20) + w)
if dist[sink] == INF:
raise Exception('No Flow Exists')
# ポテンシャルの更新
for v,d in enumerate(dist):
H[v] += d
# 流せる量を取得する
d = flow; v = sink
while v != source:
pv = prev_v[v]; pe = prev_e[v]
cap = G[pv][pe][1]
if d > cap:
d = cap
v = pv
# 流す
mincost += d * H[sink]
flow -= d
v = sink
while v != source:
pv = prev_v[v]; pe = prev_e[v]
G[pv][pe][1] -= d
rev = G[pv][pe][3]
G[v][rev][1] += d
v = pv
return mincost
INF = 10 ** 9
graph = MinCostFlow(N=8, source=0, sink=7)
add = graph.add_edge
add(0,1,me[0],0)
add(0,2,me[1],0)
add(0,3,me[2],0)
add(4,7,op[0],0)
add(5,7,op[1],0)
add(6,7,op[2],0)
# あいこ
for n in [0,1,2]:
add(n+1,n+4,INF,2) # あいこ
add(n+1,(n+1)%3 + 4,INF,0) # かち
add(n+1,(n+2)%3 + 4,INF,3) # まけ
N = sum(me)
answer = 3 * N - graph.min_cost(flow=N)
print(answer)
maspy