結果
問題 | No.177 制作進行の宮森あおいです! |
ユーザー |
![]() |
提出日時 | 2021-03-19 19:47:30 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 69 ms / 2,000 ms |
コード長 | 3,895 bytes |
コンパイル時間 | 320 ms |
コンパイル使用メモリ | 82,600 KB |
実行使用メモリ | 74,472 KB |
最終ジャッジ日時 | 2024-11-18 16:37:25 |
合計ジャッジ時間 | 1,697 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 13 |
ソースコード
from collections import dequeimport sysinput = sys.stdin.buffer.readlinesys.setrecursionlimit(10 ** 7)inf = 10**9class MF_graph(object):def __init__(self, n):self.n = nself.g = [[] for _ in range(n)] # to, rev, capself.pos = []def add_edge(self, frm, to, cap):""" frmからtoへ容量cap, 流量0の辺を追加, 何番目の辺かを返す"""m = len(self.pos)self.pos.append((frm, len(self.g[frm])))self.g[frm].append([to, len(self.g[to]), cap])self.g[to].append([frm, len(self.g[frm]) - 1, 0])return mdef __get_edge(self, i):e_to, e_rev, e_cap = self.g[self.pos[i][0]][self.pos[i][1]]re_to, _, re_cap = self.g[e_to][e_rev]# from, to, cap, flowreturn (re_to, e_to, e_cap + re_cap, re_cap)def edges(self):""" 辺の情報を返す(frm, to, cap, flow) """m = len(self.pos)for i in range(m):yield self.__get_edge(i)def change_edge(self, i, new_cap, new_flow):""" i番目に追加された辺の容量,流量をnew_cap, new_flowに変更する """f, s = self.pos[i]rf, rs, _ = self.g[f][s]self.g[f][s][2] = new_cap - new_flowself.g[rf][rs][2] = new_flowreturndef __dfs(self, s, v, up):if v == s:return upres = 0level_v = self.level[v]for i in range(self.iter[v], len(self.g[v])):u_to, u_rev, _ = self.g[v][i]if level_v <= self.level[u_to] or self.g[u_to][u_rev][2] == 0:continued = self.__dfs(s, u_to, min(up - res, self.g[u_to][u_rev][2]))if d <= 0:continueself.g[v][i][2] += dself.g[u_to][u_rev][2] -= dres += dif res == up:breakreturn resdef flow(self, s, t, flow_limit=10**18):""" sからtへflow_limitだけ流す。流せた量を返す """self.iter = [0] * self.nflow = 0while flow < flow_limit:self.level = [-1] * self.nself.level[s] = 0que = deque([s])while que:v = que.popleft()for u_to, _, u_cap in self.g[v]:if u_cap == 0 or self.level[u_to] >= 0:continueself.level[u_to] = self.level[v] + 1if u_to == t:breakque.append(u_to)if self.level[t] == -1:breakself.iter = [0] * self.nwhile flow < flow_limit:f = self.__dfs(s, t, flow_limit - flow)if not f:breakflow += freturn flowdef min_cut(self, s):""" 最小カットを返す。sから到達可能だとTrue """visited = [False] * self.nque = deque([s])while que:v = que.popleft()visited[v] = Truefor u_to, _, u_cap in self.g[v]:if u_cap and (not visited[u_to]):visited[u_to] = Trueque.append(u_to)return visitedW = int(input())N = int(input())J = tuple(map(int, input().split()))M = int(input())C = tuple(map(int, input().split()))cap = [[inf] * N for _ in range(M)]for m in range(M):_, *X = map(int, input().split())for n in X:cap[m][n-1] = 0G = MF_graph(N + M + 2)source = N + Msink = source + 1for i, j in enumerate(J):G.add_edge(source, i, j)for i, c in enumerate(C):G.add_edge(i + N, sink, c)for n in range(N):for m in range(M):G.add_edge(n, N+m, cap[m][n])flow = G.flow(source, sink)if flow >= W:print("SHIROBAKO")else:print("BANSAKUTSUKITA")