Skip to content

Commit deb6c6b

Browse files
authored
Merge pull request #61 from suisen-cp/master
Self loop handling (in flow-problem library) #43
2 parents b9de858 + 0495145 commit deb6c6b

File tree

8 files changed

+855
-301
lines changed

8 files changed

+855
-301
lines changed

MaxFlow/Main.java

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
import java.util.Arrays;
2+
import java.util.Scanner;
3+
4+
public class Main {
5+
static Solver practice2_d = new practice2_d();
6+
static Solver arc074_d = new arc074_d();
7+
static Solver abc193_f = new abc193_f();
8+
9+
public static void main(String[] args) {
10+
// practice2_d.run();
11+
// arc074_d.run();
12+
abc193_f.run();
13+
}
14+
}
15+
16+
abstract class Solver implements Runnable { public abstract void run(); }
17+
18+
/**
19+
* @problem
20+
* AtCoder Library Practice Contest D - Maxflow
21+
* {@see https://atcoder.jp/contests/practice2/tasks/practice2_d}
22+
* @submission
23+
* {@see https://atcoder.jp/contests/practice2/submissions/20808482}
24+
*/
25+
class practice2_d extends Solver {
26+
public Answer solve(int n, int m, char[][] g) {
27+
MaxFlow mf = new MaxFlow(n * m + 2);
28+
int s = n * m;
29+
int t = s + 1;
30+
for (int i = 0; i < n; i++) {
31+
for (int j = 0; j < m; j++) {
32+
if (g[i][j] == '#') continue;
33+
if (((i ^ j) & 1) == 0) {
34+
mf.addEdge(s, i * m + j, 1);
35+
} else {
36+
mf.addEdge(i * m + j, t, 1);
37+
}
38+
}
39+
}
40+
for (int i = 0; i < n; i++) {
41+
for (int j = i & 1; j < m; j += 2) {
42+
if (g[i][j] == '#') continue;
43+
if (j - 1 >= 0 && g[i][j - 1] == '.') {
44+
mf.addEdge(i * m + j, i * m + (j - 1), 1);
45+
}
46+
if (j + 1 < m && g[i][j + 1] == '.') {
47+
mf.addEdge(i * m + j, i * m + (j + 1), 1);
48+
}
49+
if (i - 1 >= 0 && g[i - 1][j] == '.') {
50+
mf.addEdge(i * m + j, (i - 1) * m + j, 1);
51+
}
52+
if (i + 1 < n && g[i + 1][j] == '.') {
53+
mf.addEdge(i * m + j, (i + 1) * m + j, 1);
54+
}
55+
}
56+
}
57+
int ans = (int) mf.maxFlow(s, t);
58+
int cnt = 0;
59+
for (var e : mf.getEdges()) {
60+
if (e.flow == 0) continue;
61+
int u = e.from;
62+
int v = e.to;
63+
if (u == s || v == t) continue;
64+
int ui = u / m, uj = u % m;
65+
int vi = v / m, vj = v % m;
66+
if (g[ui][uj] != '.' || g[vi][vj] != '.') {
67+
throw new AssertionError();
68+
}
69+
if (ui == vi) {
70+
if (uj + 1 == vj) {
71+
g[ui][uj] = '>';
72+
g[vi][vj] = '<';
73+
} else if (uj == vj + 1) {
74+
g[ui][uj] = '<';
75+
g[vi][vj] = '>';
76+
} else {
77+
throw new AssertionError();
78+
}
79+
} else if (uj == vj) {
80+
if (ui + 1 == vi) {
81+
g[ui][uj] = 'v';
82+
g[vi][vj] = '^';
83+
} else if (ui == vi + 1) {
84+
g[ui][uj] = '^';
85+
g[vi][vj] = 'v';
86+
} else {
87+
throw new AssertionError();
88+
}
89+
} else {
90+
throw new AssertionError();
91+
}
92+
cnt++;
93+
}
94+
if (ans != cnt) throw new AssertionError();
95+
return new Answer(ans, g);
96+
}
97+
98+
static class Answer {
99+
final int c;
100+
final char[][] g;
101+
Answer(int c, char[][] g) { this.c = c; this.g = g; }
102+
@Override
103+
public String toString() {
104+
StringBuilder sb = new StringBuilder();
105+
sb.append(c);
106+
for (char[] row : g) {
107+
sb.append('\n').append(row);
108+
}
109+
return sb.toString();
110+
}
111+
}
112+
113+
public void run() {
114+
Scanner sc = new Scanner(System.in);
115+
int n = Integer.parseInt(sc.next());
116+
int m = Integer.parseInt(sc.next());
117+
char[][] g = new char[n][];
118+
Arrays.setAll(g, i -> sc.next().toCharArray());
119+
sc.close();
120+
System.out.println(solve(n, m, g));
121+
}
122+
}
123+
124+
/**
125+
* @problem
126+
* AtCoder Regular Contest 074 F - Lotus Leaves
127+
* {@see https://atcoder.jp/contests/arc074/tasks/arc074_d}
128+
* @submission
129+
* {@see https://atcoder.jp/contests/arc074/submissions/20808863}
130+
*/
131+
class arc074_d extends Solver {
132+
static final int INF = 1 << 20;
133+
public int solve(int h, int w, char[][] g) {
134+
int si = -1, sj = -1, ti = -1, tj = -1;
135+
boolean[][] grid = new boolean[h][w];
136+
for (int i = 0; i < h; i++) {
137+
for (int j = 0; j < w; j++) {
138+
if (g[i][j] == 'S') {
139+
si = i; sj = j;
140+
grid[i][j] = true;
141+
} else if (g[i][j] == 'T') {
142+
ti = i; tj = j;
143+
grid[i][j] = true;
144+
} else if (g[i][j] == 'o') {
145+
grid[i][j] = true;
146+
}
147+
}
148+
}
149+
int s = h + w;
150+
int t = s + 1;
151+
MaxFlow mf = new MaxFlow(h + w + 2);
152+
mf.addEdge(s , si , INF);
153+
mf.addEdge(s , sj + h, INF);
154+
mf.addEdge(ti , t , INF);
155+
mf.addEdge(tj + h, t , INF);
156+
for (int i = 0; i < h; i++) {
157+
for (int j = 0; j < w; j++) {
158+
if (grid[i][j]) {
159+
mf.addEdge(i, j + h, 1);
160+
mf.addEdge(j + h, i, 1);
161+
}
162+
}
163+
}
164+
int flow = (int) mf.maxFlow(s, t);
165+
return flow >= INF ? -1 : flow;
166+
}
167+
168+
public void run() {
169+
Scanner sc = new Scanner(System.in);
170+
int h = Integer.parseInt(sc.next());
171+
int w = Integer.parseInt(sc.next());
172+
char[][] g = new char[h][];
173+
Arrays.setAll(g, i -> sc.next().toCharArray());
174+
sc.close();
175+
System.out.println(solve(h, w, g));
176+
}
177+
}
178+
179+
/**
180+
* @problem
181+
* AtCoder Beginner Contest 193 F - Zebraness
182+
* {@see https://atcoder.jp/contests/abc193/tasks/abc193_f}
183+
* @submission
184+
* {@see https://atcoder.jp/contests/abc193/submissions/20808965}
185+
*/
186+
class abc193_f extends Solver {
187+
static final int[] dx4 = {1, 0, -1, 0};
188+
static final int[] dy4 = {0, 1, 0, -1};
189+
190+
public int solve(int n, char[][] c) {
191+
int[][] id = new int[n][n];
192+
int cnt = 0;
193+
for (int i = 0; i < n; i++) {
194+
for (int j = 0; j < n; j++) {
195+
if (c[i][j] == '?') {
196+
id[i][j] = cnt++;
197+
}
198+
}
199+
}
200+
201+
int ans = 0;
202+
for (int i = 0; i < n; i++) {
203+
for (int j = 0; j < n; j++) {
204+
if (i < n - 1) {
205+
if (c[i][j] == 'B' && c[i + 1][j] == 'W' || c[i][j] == 'W' && c[i + 1][j] == 'B') {
206+
ans++;
207+
}
208+
}
209+
if (j < n - 1) {
210+
if (c[i][j] == 'B' && c[i][j + 1] == 'W' || c[i][j] == 'W' && c[i][j + 1] == 'B') {
211+
ans++;
212+
}
213+
}
214+
}
215+
}
216+
MaxFlow mf = new MaxFlow(cnt + 2);
217+
int s = cnt, t = cnt + 1;
218+
for (int i = 0; i < n; i++) {
219+
for (int j = 0; j < n; j++) {
220+
if (c[i][j] == '?') {
221+
int b = 0, w = 0;
222+
for (int d = 0; d < 4; d++) {
223+
int ni = i + dx4[d];
224+
int nj = j + dy4[d];
225+
if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue;
226+
if (c[ni][nj] == 'B') {
227+
b++;
228+
} else if (c[ni][nj] == 'W') {
229+
w++;
230+
} else if (d < 2) {
231+
mf.addEdge(id[i][j], id[ni][nj], 1);
232+
mf.addEdge(id[ni][nj], id[i][j], 1);
233+
ans++;
234+
}
235+
}
236+
mf.addEdge(id[i][j], t, (i + j) % 2 == 1 ? b : w);
237+
mf.addEdge(s, id[i][j], (i + j) % 2 == 1 ? w : b);
238+
ans += b + w;
239+
}
240+
}
241+
}
242+
return (int) (ans - mf.maxFlow(s, t));
243+
}
244+
245+
public void run() {
246+
Scanner sc = new Scanner(System.in);
247+
int n = Integer.parseInt(sc.next());
248+
char[][] c = new char[n][];
249+
Arrays.setAll(c, i -> sc.next().toCharArray());
250+
sc.close();
251+
System.out.println(solve(n, c));
252+
}
253+
}

0 commit comments

Comments
 (0)