結果
| 問題 |
No.1301 Strange Graph Shortest Path
|
| コンテスト | |
| ユーザー |
tktk_snsn
|
| 提出日時 | 2020-11-27 23:58:14 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,143 bytes |
| コンパイル時間 | 322 ms |
| コンパイル使用メモリ | 13,184 KB |
| 実行使用メモリ | 168,236 KB |
| 最終ジャッジ日時 | 2024-07-26 20:31:09 |
| 合計ジャッジ時間 | 88,822 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 27 TLE * 6 |
ソースコード
import heapq
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)
class MCF_graph(object):
def __init__(self, n):
self.n = n
self.g = [[] for _ in range(n)] # to, rev, cap, cost
self.pos = []
def add_edge(self, frm, to, cap, cost):
m = len(self.pos)
self.pos.append((frm, len(self.g[frm])))
self.g[frm].append([to, len(self.g[to]), cap, cost])
self.g[to].append([frm, len(self.g[frm]) - 1, 0, -cost])
return m
def __get_edge(self, i):
e_to, e_rev, e_cap, e_cost = self.g[self.pos[i][0]][self.pos[i][1]]
re_to, _, re_cap, _ = self.g[e_to][e_rev]
# from, to, cap, flow, cost
return (re_to, e_to, e_cap + re_cap, re_cap, e_cost)
def edges(self):
m = len(self.pos)
for i in range(m):
yield self.__get_edge(i)
def flow(self, s, t, flow_limit=10**18):
return self.slope(s, t, flow_limit)[-1]
def slope(self, s, t, flow_limit=10**18):
dual = [0] * self.n
flow = 0
cost = 0
prev_cost = -1
result = [(0, 0)] # cap, cost
while flow < flow_limit:
# call dual_ref()
dist = [10**18] * self.n
pv = [-1] * self.n
pe = [-1] * self.n
vis = [False] * self.n
dist[s] = 0
que = [(0, s)]
while que:
_, v = heapq.heappop(que)
if vis[v]:
continue
vis[v] = True
if v == t:
break
for i, (e_to, _, e_cap, e_cost) in enumerate(self.g[v]):
if vis[e_to] or (not e_cap):
continue
tmp_cost = e_cost - dual[e_to] + dual[v]
if dist[e_to] > dist[v] + tmp_cost:
dist[e_to] = dist[v] + tmp_cost
pv[e_to] = v
pe[e_to] = i
heapq.heappush(que, (dist[e_to], e_to))
if not vis[t]:
break
for v, visited in enumerate(vis):
if not visited:
continue
dual[v] -= dist[t] - dist[v]
# end dual_ref()
c = flow_limit - flow
v = t
while v != s:
c = min(c, self.g[pv[v]][pe[v]][2])
v = pv[v]
v = t
while v != s:
i, j = pv[v], pe[v]
self.g[i][j][2] -= c
self.g[v][self.g[i][j][1]][2] += c
v = i
d = -dual[s]
flow += c
cost += c * d
if prev_cost == d:
result.pop()
result.append((flow, cost))
prev_cost = cost
return result
n, m = map(int, input().split())
g = MCF_graph(n)
for _ in range(m):
a, b, c, d = map(int, input().split())
a -= 1
b -= 1
g.add_edge(a, b, 1, c)
g.add_edge(a, b, 1, d)
g.add_edge(b, a, 1, c)
g.add_edge(b, a, 1, d)
res = g.flow(0, n - 1, 2)[-1]
print(res)
tktk_snsn