1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
| # 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
import sys
from collections import deque
def dinic_maxflow(n, s, t, graph):
level = [-1] * n
work = [0] * n
def bfs():
for i in range(n):
level[i] = -1
q = deque([s])
level[s] = 0
while q:
u = q.popleft()
for v, cap, rev in graph[u]:
if cap > 0 and level[v] == -1:
level[v] = level[u] + 1
q.append(v)
return level[t] != -1
def dfs(u, f):
if u == t:
return f
i = work[u]
while i < len(graph[u]):
v, cap, rev = graph[u][i]
if cap > 0 and level[v] == level[u] + 1:
pushed = dfs(v, f if f < cap else cap)
if pushed:
graph[u][i][1] -= pushed
graph[v][rev][1] += pushed
return pushed
i += 1
work[u] = i
return 0
flow = 0
INF = 10 ** 30
while bfs():
for i in range(n):
work[i] = 0
while True:
pushed = dfs(s, INF)
if not pushed:
break
flow += pushed
return flow
def add_edge(graph, u, v, c):
graph[u].append([v, c, len(graph[v])])
graph[v].append([u, 0, len(graph[u]) - 1])
def main():
input = sys.stdin.readline
N_line = input().strip()
if not N_line:
return
N = int(N_line)
S, T = 0, N + 1
n = N + 2
graph = [[] for _ in range(n)]
force = [0] * (N + 1)
vals = list(map(int, input().split()))
for i in range(1, N + 1):
force[i] = vals[i - 1]
W = [list(map(int, input().split())) for _ in range(N)]
for i in range(N):
for j in range(i + 1, N):
w = W[i][j]
if w:
add_edge(graph, i + 1, j + 1, w)
add_edge(graph, j + 1, i + 1, w)
INF = 10 ** 30
for i in range(1, N + 1):
if force[i] == 1:
add_edge(graph, S, i, INF)
elif force[i] == 2:
add_edge(graph, i, T, INF)
min_cut = dinic_maxflow(n, S, T, graph)
print(min_cut)
# BFS on residual to get partition
vis = [False] * n
dq = deque([S])
vis[S] = True
while dq:
u = dq.popleft()
for v, cap, _ in graph[u]:
if cap > 0 and not vis[v]:
vis[v] = True
dq.append(v)
A = [str(i) for i in range(1, N + 1) if vis[i]]
B = [str(i) for i in range(1, N + 1) if not vis[i]]
print(" ".join(A))
print(" ".join(B))
if __name__ == "__main__":
main()
|