結果
問題 | No.2286 Join Hands |
ユーザー |
👑 |
提出日時 | 2024-04-29 21:54:33 |
言語 | PyPy3 (7.3.15) |
結果 |
MLE
|
実行時間 | - |
コード長 | 5,836 bytes |
コンパイル時間 | 212 ms |
コンパイル使用メモリ | 82,136 KB |
実行使用メモリ | 1,701,940 KB |
最終ジャッジ日時 | 2024-11-19 06:11:26 |
合計ジャッジ時間 | 117,001 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 MLE * 2 |
other | AC * 15 TLE * 13 MLE * 30 |
ソースコード
import heapqfrom dataclasses import dataclassclass mcf_graph:@dataclassclass edge:from_: intto: intcap: intflow: intcost: int# def __init__(self, from_, to, cap, flow, cost):# self.from_ = from_# self.to = to# self.cap = cap# self.flow = flow# self.cost = cost@dataclassclass _edge:to: intrev: intcap: intcost: int# def __init__(self, to, rev, cap, cost):# self.to = to# self.rev = rev# self.cap = cap# self.cost = costdef __init__(self, n, inf=1 << 60):self.n = nself._edges = []self.inf = infdef add_edge(self, from_, to, cap, cost):m = len(self._edges)self._edges.append(mcf_graph.edge(from_, to, cap, 0, cost))return mdef get_edge(self, i):return self._edges[i]def edges(self):return self._edgesdef flow(self, s, t, flow_limit=1 << 60):return self.slope(s, t, flow_limit)[-1]class csr:def __init__(self, n, elist):self.start = [0] * (n + 1)self.elist = [None] * len(elist)for e in elist:self.start[e[0] + 1] += 1for i in range(1, n + 1):self.start[i] += self.start[i - 1]counter = self.start[:]for e in elist:self.elist[counter[e[0]]] = mcf_graph._edge(e[1].to, e[1].rev, e[1].cap, e[1].cost)counter[e[0]] += 1def slope(self, s, t, flow_limit=1 << 60):m = len(self._edges)edge_idx = [0] * mdegree = [0] * self.nredge_idx = [0] * melist = [0] * (2 * m)for i in range(m):e = self._edges[i]edge_idx[i] = degree[e.from_]degree[e.from_] += 1redge_idx[i] = degree[e.to]degree[e.to] += 1elist[2 * i] = (e.from_, mcf_graph._edge(e.to, -1, e.cap - e.flow, e.cost))elist[2 * i + 1] = (e.to, mcf_graph._edge(e.from_, -1, e.flow, -e.cost))g = mcf_graph.csr(self.n, elist)for i in range(m):e = self._edges[i]edge_idx[i] += g.start[e.from_]redge_idx[i] += g.start[e.to]g.elist[edge_idx[i]].rev = redge_idx[i]g.elist[redge_idx[i]].rev = edge_idx[i]result = self._slope(g, s, t, flow_limit)for i in range(m):e = g.elist[edge_idx[i]]self._edges[i].flow = self._edges[i].cap - e.capreturn resultdef _slope(self, g, s, t, flow_limit):dual_dist = [[0, 0] for _ in range(self.n)]prev_e = [None] * self.nvis = [False] * self.nque_min = []que = []def dual_ref():for i in range(self.n):dual_dist[i][1] = self.infnonlocal vis, que_min, quevis = [False] * self.nque = []que_min = [s]dual_dist[s][1] = 0while que_min or que:if que_min:v = que_min.pop()else:v = heapq.heappop(que)[1]if vis[v]:continuevis[v] = Trueif v == t:breakdual_v, dist_v = dual_dist[v]for i in range(g.start[v], g.start[v + 1]):e = g.elist[i]if e.cap == 0:continuecost = e.cost - dual_dist[e.to][0] + dual_vif dual_dist[e.to][1] - dist_v > cost:dist_to = dist_v + costdual_dist[e.to][1] = dist_toprev_e[e.to] = e.revif dist_to == dist_v:heapq.heappush(que_min, e.to)else:heapq.heappush(que, (dist_to, e.to))if not vis[t]:return Falsefor v in range(self.n):if not vis[v]:continuedual_dist[v][0] -= dual_dist[t][1] - dual_dist[v][1]return Trueflow = 0cost = 0prev_cost_per_flow = -1result = [(0, 0)]while flow < flow_limit:if not dual_ref():breakc = flow_limit - flowv = twhile v != s:c = min(c, g.elist[g.elist[prev_e[v]].rev].cap)v = g.elist[prev_e[v]].tov = twhile v != s:e = g.elist[prev_e[v]]g.elist[prev_e[v]].cap += cg.elist[e.rev].cap -= cv = e.tod = -dual_dist[s][0]flow += ccost += c * dif prev_cost_per_flow == d:result.pop()result.append((flow, cost))prev_cost_per_flow = dreturn resultn, m = map(int, input().split())G = mcf_graph(2 * n + 2)s = 2 * nt = s + 1for i in range(n):G.add_edge(s, i, 1, 0)G.add_edge(n + i, t, 1, 0)E = [[False] * n for _ in range(n)]for _ in range(m):u, v = map(int, input().split())u -= 1v -= 1E[u][v] = E[v][u] = Truefor u in range(n):for v in range(n):cost: intif E[u][v]:cost = 0elif u == v:cost = 100else:cost = 1G.add_edge(u, n + v, 1, cost)G.add_edge(v, n + u, 1, cost)res = G.flow(s, t)ans = n - 2 * res[1]print(ans)