結果
| 問題 | No.3699 引き抜き交渉 |
| コンテスト | |
| ユーザー |
とりゐ
|
| 提出日時 | 2026-09-09 21:29:21 |
| 言語 | PyPy3 (7.3.23 + ACL) |
| 結果 |
AC
不安定
|
| 実行時間 | 104 ms / 2,000 ms |
| + 251µs | |
| コード長 | 4,694 bytes |
| 記録 | |
| コンパイル時間 | 74 ms |
| コンパイル使用メモリ | 82,128 KB |
| 実行使用メモリ | 87,552 KB |
| 最終ジャッジ日時 | 2026-09-09 21:30:02 |
| 合計ジャッジ時間 | 2,491 ms |
|
ジャッジサーバーID (参考情報) |
judge1_0 / judge3_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 15 |
ソースコード
class MaxFlow:
_INF = 9_223_372_036_854_775_807
def __init__(self, n=0):
self._n = n
self._pos = []
self._g = [[] for _ in range(n)] # [to, rev, cap]
def add_edge(self, from_, to, cap):
assert 0 <= from_ < self._n
assert 0 <= to < self._n
assert 0 <= cap
m = len(self._pos)
from_id = len(self._g[from_])
self._pos.append([from_, from_id])
to_id = len(self._g[to])
if from_ == to:
to_id += 1
self._g[from_].append([to, to_id, cap])
self._g[to].append([from_, from_id, 0])
return m
def get_edge(self, i):
m = len(self._pos)
assert 0 <= i < m
_e = self._g[self._pos[i][0]][self._pos[i][1]]
_re = self._g[_e[0]][_e[1]]
return [self._pos[i][0], _e[0], _e[2] + _re[2], _re[2]] # from, to, cap, flow
def edges(self):
m = len(self._pos)
result = [self.get_edge(i) for i in range(m)]
return result
def change_edge(self, i, new_cap, new_flow):
m = len(self._pos)
assert 0 <= i < m
assert 0 <= new_flow <= new_cap
_e = self._g[self._pos[i][0]][self._pos[i][1]]
_re = self._g[_e[0]][_e[1]]
_e[2] = new_cap - new_flow
_re[2] = new_flow
def _flow_bfs(self, s, t):
level = [-1] * self._n
level[s] = 0
que = [s]
while que:
next_que = []
for v in que:
for to, rev, cap in self._g[v]:
if cap == 0 or level[to] >= 0:
continue
level[to] = level[v] + 1
if to == t:
return level
next_que.append(to)
que, next_que = next_que, que
return level
def flow(self, s, t, flow_limit=_INF):
assert 0 <= s < self._n
assert 0 <= t < self._n
assert s != t
flow = 0
while flow < flow_limit:
level = self._flow_bfs(s, t)
if level[t] == -1:
break
iterator = [0] * self._n
in_ = [0] * self._n
out = [0] * self._n
in_[t] = flow_limit - flow
route = [t]
while route:
v = route[-1]
if in_[v] == out[v] and v == t:
flow += out[t]
return flow
if v == s or in_[v] == out[v]:
route.pop()
w = route[-1]
flow_vw = in_[v]
i = iterator[w]
to, rev, cap = self._g[w][i]
self._g[v][rev][2] -= flow_vw
self._g[w][i][2] += flow_vw
out[w] += flow_vw
continue
for i in range(iterator[v], len(self._g[v])):
to, rev, cap = self._g[v][i]
if level[to] == -1 or level[v] <= level[to] or self._g[to][rev][2] == 0:
continue
in_[to] = min(in_[v] - out[v], self._g[to][rev][2])
out[to] = 0
route.append(to)
iterator[v] = i
break
else:
iterator[v] = len(self._g[v])
route.pop()
if v == t:
if out[t] == 0:
return flow
flow += out[t]
continue
w = route[-1]
flow_vw = out[v]
i = iterator[w]
to, rev, cap = self._g[w][i]
self._g[v][rev][2] -= flow_vw
self._g[w][i][2] += flow_vw
out[w] += flow_vw
iterator[w] += 1
return flow
def min_cut(self, s):
visited = [False] * self._n
visited[s] = True
que = [s]
while que:
next_que = []
for p in que:
for to, rev, cap in self._g[p]:
if cap > 0 and not visited[to]:
visited[to] = True
next_que.append(to)
que, next_que = next_que, que
return visited
n, m = map(int, input().split())
S = n
T = S + 1
ans = 0
G = MaxFlow(n + 2)
for i in range(n):
a, b = map(int, input().split())
G.add_edge(S, i, a)
G.add_edge(i, T, b)
ans += a + b
for _ in range(m):
u, v, c = map(int, input().split())
u -= 1
v -= 1
G.add_edge(u, v, c)
G.add_edge(v, u, c)
print(ans - G.flow(S, T))
とりゐ