結果
問題 | No.1301 Strange Graph Shortest Path |
ユーザー |
|
提出日時 | 2020-11-07 10:50:51 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 2,412 ms / 3,000 ms |
コード長 | 4,164 bytes |
コンパイル時間 | 293 ms |
コンパイル使用メモリ | 82,112 KB |
実行使用メモリ | 313,880 KB |
最終ジャッジ日時 | 2024-09-13 00:44:25 |
合計ジャッジ時間 | 62,214 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 33 |
ソースコード
import sysimport heapqinput = sys.stdin.readlineclass mcf_graph:def __init__(self, n):self.n = nself.pos = []self.g = [[] for _ in range(n)]def add_edge(self, from_, to, cap, cost):# assert 0 <= from_ < self.n# assert 0 <= to < self.nm = len(self.pos)self.pos.append((from_, len(self.g[from_])))self.g[from_].append(self.__class__._edge(to, len(self.g[to]), cap, cost))self.g[to].append(self.__class__._edge(from_, len(self.g[from_]) - 1, 0, -cost))return mclass edge:def __init__(self, from_, to, cap, flow, cost):self.from_ = from_self.to = toself.cap = capself.flow = flowself.cost = costdef get_edge(self, i):_e = self.g[self.pos[i][0]][self.pos[i][1]]_re = self.g[_e.to][_e.rev]return self.__class__.edge(self.pos[i][0], _e.to, _e.cap + _re.cap, _re.cap, _e.cost)def edges(self):ret = []for i in range(len(self.pos)):_e = self.g[self.pos[i][0]][self.pos[i][1]]_re = self.g[_e.to][_e.rev]ret.append(self.__class__.edge(self.pos[i][0], _e.to, _e.cap + _re.cap, _re.cap, _e.cost))return retdef slope(self, s, t, flow_limit=float('inf')):# assert 0 <= s < self.n# assert 0 <= t < self.n# assert s != tdual = [0] * self.ndist = [float('inf')] * self.npv = [-1] * self.npe = [-1] * self.nvis = [False] * self.ndef _dual_ref():nonlocal dual, dist, pv, pe, visdist = [float('inf')] * self.npv = [-1] * self.npe = [-1] * self.nvis = [False] * self.nque = [(0, s)]dist[s] = 0while que:_, v = heapq.heappop(que)if vis[v]:continuevis[v] = Trueif v == t:breakfor i in range(len(self.g[v])):e = self.g[v][i]if vis[e.to] or e.cap == 0:continuecost = e.cost - dual[e.to] + dual[v]if dist[e.to] > dist[v] + cost:dist[e.to] = dist[v] + costpv[e.to] = vpe[e.to] = iheapq.heappush(que, (dist[e.to], e.to))if not vis[t]:return Falsefor v in range(self.n):if not vis[v]:continuedual[v] -= dist[t] - dist[v]return Trueflow = 0cost = 0prev_cost = -1result = [(flow, cost)]while flow < flow_limit:if not _dual_ref():breakc = flow_limit - flowv = twhile v != s:c = min(c, self.g[pv[v]][pe[v]].cap)v = pv[v]v = twhile v != s:e = self.g[pv[v]][pe[v]]e.cap -= cself.g[v][e.rev].cap += cv = pv[v]d = -dual[s]flow += ccost += c * dif prev_cost == d:result.pop()result.append((flow, cost))prev_cost = costreturn resultdef flow(self, s, t, flow_limit=float('inf')):return self.slope(s, t, flow_limit)[-1]class _edge:def __init__(self, to, rev, cap, cost):self.to = toself.rev = revself.cap = capself.cost = costN, M = map(int, input().split())g = mcf_graph(N + 2 * M)for i in range(M):u, v, c, d = map(int, input().split())u -= 1v -= 1u2 = N + iv2 = N + M + ig.add_edge(u, u2, 2, 0)g.add_edge(v, u2, 2, 0)g.add_edge(u2, v2, 1, c)g.add_edge(u2, v2, 1, d)g.add_edge(v2, u, 2, 0)g.add_edge(v2, v, 2, 0)print(g.flow(0, N - 1, 2)[1])