diff --git a/README.md b/README.md index b866021..8a35ef5 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ ac-library-python is a Python port of [AtCoder Library (ACL)](https://atcoder.jp #### Graph + [Disjoint Set Union (DSU)](https://github.com/atcoder/ac-library/blob/master/document_en/dsu.md) ++ maxflow ++ mincostflow + scc ### Work in progress @@ -40,8 +42,6 @@ ac-library-python is a Python port of [AtCoder Library (ACL)](https://atcoder.jp #### Graph -+ maxflow -+ mincostflow + twosat ## Install diff --git a/README_ja.md b/README_ja.md index 811e765..098f6dc 100644 --- a/README_ja.md +++ b/README_ja.md @@ -21,6 +21,8 @@ ac-library-pythonは、[AtCoder Library (ACL)](https://atcoder.jp/posts/517)のP #### グラフ + [Disjoint Set Union (DSU)](https://github.com/atcoder/ac-library/blob/master/document_ja/dsu.md) ++ maxflow ++ mincostflow + scc ### 準備中 @@ -38,8 +40,6 @@ ac-library-pythonは、[AtCoder Library (ACL)](https://atcoder.jp/posts/517)のP #### グラフ -+ maxflow -+ mincostflow + twosat ## インストール diff --git a/atcoder/maxflow.py b/atcoder/maxflow.py index 8e49f73..ecd820e 100644 --- a/atcoder/maxflow.py +++ b/atcoder/maxflow.py @@ -141,66 +141,3 @@ def min_cut(self, s: int) -> List[bool]: visited[e.dst] = True stack.append(e.dst) return visited - - -# https://atcoder.jp/contests/practice2/tasks/practice2_d -def main() -> None: - import sys - n, m = map(int, sys.stdin.readline().split()) - s = n * m - t = s + 1 - g = MFGraph(t + 1) - grid = [list(sys.stdin.readline().strip()) for _ in range(n)] - - def enc(i: int, j: int) -> int: - return i * m + j - - def dec(v: int) -> (int, int): - return v // m, v % m - - for i in range(n): - for j in range(m): - if grid[i][j] == '#': - continue - if (i + j) % 2 == 0: - g.add_edge(s, enc(i, j), 1) - else: - g.add_edge(enc(i, j), t, 1) - - dx = [1, 0, -1, 0] - dy = [0, 1, 0, -1] - for i in range(n): - for j in range(m): - if (i + j) % 2 == 1 or grid[i][j] == '#': - continue - for direction in range(4): - ii = i + dx[direction] - jj = j + dy[direction] - if 0 <= ii < n and 0 <= jj < m and grid[ii][jj] == '.': - g.add_edge(enc(i, j), enc(ii, jj), 1) - - print(g.flow(s, t)) - for e in g.edges(): - if e.src == s or e.dst == t or e.flow == 0: - continue - (i, j) = dec(e.src) - (ii, jj) = dec(e.dst) - if i == ii + 1: - grid[ii][jj] = 'v' - grid[i][j] = '^' - elif j == jj + 1: - grid[ii][jj] = '>' - grid[i][j] = '<' - elif i == ii - 1: - grid[i][j] = 'v' - grid[ii][jj] = '^' - else: - grid[i][j] = '>' - grid[ii][jj] = '<' - - for s in grid: - print("".join(s)) - - -if __name__ == '__main__': - main() diff --git a/atcoder/mincostflow.py b/atcoder/mincostflow.py index 41431e5..4bf6f75 100644 --- a/atcoder/mincostflow.py +++ b/atcoder/mincostflow.py @@ -125,37 +125,3 @@ def refine_dual() -> bool: result.append((flow, cost)) prev_cost_per_flow = c return result - - -# https://atcoder.jp/contests/practice2/tasks/practice2_e -def main() -> None: - import sys - n, k = map(int, sys.stdin.readline().split()) - s = n * 2 - t = s + 1 - g = MCFGraph(t + 1) - grid = [list(map(int, sys.stdin.readline().split())) for _ in range(n)] - big = 10 ** 9 - edges = list([] for _ in range(n)) - for i in range(n): - g.add_edge(s, i, k, 0) - g.add_edge(i + n, t, k, 0) - for j in range(n): - edges[i].append(g.add_edge(i, j + n, 1, big - grid[i][j])) - g.add_edge(s, t, n * k, big) - - cost = g.flow(s, t, n * k)[1] - print(big * n * k - cost) - - result = list(['.'] * n for _ in range(n)) - for i in range(n): - for j in range(n): - if g.get_edge(edges[i][j]).flow > 0: - result[i][j] = 'X' - - for s in result: - print("".join(s)) - - -if __name__ == '__main__': - main() diff --git a/example/dsu_practice.py b/example/dsu_practice.py index 069b6d2..083c4e9 100644 --- a/example/dsu_practice.py +++ b/example/dsu_practice.py @@ -1,11 +1,11 @@ # https://atcoder.jp/contests/practice2/tasks/practice2_a +import sys + from atcoder.dsu import DSU def main() -> None: - import sys - n, q = map(int, sys.stdin.readline().split()) dsu = DSU(n) diff --git a/example/fenwick_practice.py b/example/fenwick_practice.py index 263a454..15f3b76 100644 --- a/example/fenwick_practice.py +++ b/example/fenwick_practice.py @@ -1,11 +1,11 @@ # https://atcoder.jp/contests/practice2/tasks/practice2_b +import sys + from atcoder.fenwicktree import FenwickTree def main() -> None: - import sys - n, q = map(int, sys.stdin.readline().split()) fenwick_tree = FenwickTree(n) diff --git a/example/floor_sum_practice.py b/example/floor_sum_practice.py index 00dfc56..0c55ca1 100644 --- a/example/floor_sum_practice.py +++ b/example/floor_sum_practice.py @@ -1,11 +1,11 @@ # https://atcoder.jp/contests/practice2/tasks/practice2_c +import sys + from atcoder.math import floor_sum def main() -> None: - import sys - t = int(sys.stdin.readline()) for _ in range(t): n, m, a, b = map(int, sys.stdin.readline().split()) diff --git a/example/maxflow_practice.py b/example/maxflow_practice.py new file mode 100644 index 0000000..6112340 --- /dev/null +++ b/example/maxflow_practice.py @@ -0,0 +1,66 @@ +# https://atcoder.jp/contests/practice2/tasks/practice2_d + +import sys + +from atcoder.maxflow import MFGraph + + +def main() -> None: + n, m = map(int, sys.stdin.readline().split()) + s = n * m + t = s + 1 + g = MFGraph(t + 1) + grid = [list(sys.stdin.readline().strip()) for _ in range(n)] + + def enc(i: int, j: int) -> int: + return i * m + j + + def dec(v: int) -> (int, int): + return v // m, v % m + + for i in range(n): + for j in range(m): + if grid[i][j] == '#': + continue + if (i + j) % 2 == 0: + g.add_edge(s, enc(i, j), 1) + else: + g.add_edge(enc(i, j), t, 1) + + dx = [1, 0, -1, 0] + dy = [0, 1, 0, -1] + for i in range(n): + for j in range(m): + if (i + j) % 2 == 1 or grid[i][j] == '#': + continue + for direction in range(4): + ii = i + dx[direction] + jj = j + dy[direction] + if 0 <= ii < n and 0 <= jj < m and grid[ii][jj] == '.': + g.add_edge(enc(i, j), enc(ii, jj), 1) + + print(g.flow(s, t)) + for e in g.edges(): + if e.src == s or e.dst == t or e.flow == 0: + continue + (i, j) = dec(e.src) + (ii, jj) = dec(e.dst) + if i == ii + 1: + grid[ii][jj] = 'v' + grid[i][j] = '^' + elif j == jj + 1: + grid[ii][jj] = '>' + grid[i][j] = '<' + elif i == ii - 1: + grid[i][j] = 'v' + grid[ii][jj] = '^' + else: + grid[i][j] = '>' + grid[ii][jj] = '<' + + for s in grid: + print("".join(s)) + + +if __name__ == '__main__': + main() diff --git a/example/mincostflow_practice.py b/example/mincostflow_practice.py new file mode 100644 index 0000000..144767d --- /dev/null +++ b/example/mincostflow_practice.py @@ -0,0 +1,37 @@ +# https://atcoder.jp/contests/practice2/tasks/practice2_e + +import sys + +from atcoder.mincostflow import MCFGraph + + +def main() -> None: + n, k = map(int, sys.stdin.readline().split()) + s = n * 2 + t = s + 1 + g = MCFGraph(t + 1) + grid = [list(map(int, sys.stdin.readline().split())) for _ in range(n)] + big = 10 ** 9 + edges = list([] for _ in range(n)) + for i in range(n): + g.add_edge(s, i, k, 0) + g.add_edge(i + n, t, k, 0) + for j in range(n): + edges[i].append(g.add_edge(i, j + n, 1, big - grid[i][j])) + g.add_edge(s, t, n * k, big) + + cost = g.flow(s, t, n * k)[1] + print(big * n * k - cost) + + result = list(['.'] * n for _ in range(n)) + for i in range(n): + for j in range(n): + if g.get_edge(edges[i][j]).flow > 0: + result[i][j] = 'X' + + for s in result: + print("".join(s)) + + +if __name__ == '__main__': + main()