aboutsummaryrefslogtreecommitdiff
path: root/2023/25
diff options
context:
space:
mode:
Diffstat (limited to '2023/25')
-rw-r--r--2023/25/25a.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/2023/25/25a.c b/2023/25/25a.c
new file mode 100644
index 0000000..7626c74
--- /dev/null
+++ b/2023/25/25a.c
@@ -0,0 +1,95 @@
1#include <inttypes.h>
2#include <stdbool.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#define N 1500
8#define M 15000
9#define MIN(x,y) ((x)<(y)?(x):(y))
10#define ischar(c) (c >= 'a' && c <= 'z')
11
12typedef struct {
13 int nout, out[N];
14 char s[4], outc[N][4];
15} node_t;
16
17bool visited[N];
18char *buf, line[N][N];
19int n, nother, c[N][N], f[N][N];
20node_t m[N];
21
22int findm(char *s) {
23 for (int k = 0; k < n; k++)
24 if (m[k].s[0] == s[0] && m[k].s[1] == s[1] && m[k].s[2] == s[2])
25 return k;
26 return n;
27}
28
29void resetfc(void) {
30 for (int i = 0; i < n; i++)
31 for (int j = 0; j < m[i].nout; j++)
32 c[i][m[i].out[j]] = 1;
33 for (int i = 0; i < n; i++)
34 memset(f[i], 0, N * sizeof(int));
35}
36
37bool dfs(int v, int t) {
38 if (v == t) return true;
39 if (visited[v]) return false;
40 visited[v] = true;
41 for (int i = 0; i < m[v].nout; i++) {
42 int u = m[v].out[i];
43 if (c[v][u] == 0) continue;
44 c[v][u]--;
45 c[u][v]++;
46 f[v][u]++;
47 if (dfs(u, t)) return true;
48 c[v][u]++;
49 c[u][v]--;
50 f[v][u]--;
51 }
52 return false;
53}
54
55bool residualpath(int s, int t) {
56 memset(visited, 0, N * sizeof(bool));
57 return dfs(s, t);
58}
59
60/* Ford-Fulkerson */
61bool flowatmost(int s, int t, int k) {
62 int flow;
63 resetfc();
64 for (flow = 0; flow <= k && residualpath(s, t); flow++) ;
65 return flow <= k;
66}
67
68int main() {
69 for (n = 0; (buf = fgets(line[n], N, stdin)) != NULL; n++) {
70 for (int i = 0; ischar(*buf); m[n].s[i++] = *(buf++)) ;
71 for (int i = 0; *buf != '\n'; i++) {
72 while (!ischar(*buf)) buf++;
73 for (int j = 0; ischar(*buf); m[n].outc[i][j++] = *(buf++)) ;
74 }
75 }
76
77 for (int i = 0; i < n; i++) {
78 for (int j = 0; m[i].outc[j][0]; j++) {
79 int k = findm(m[i].outc[j]);
80 m[i].out[m[i].nout++] = k;
81 m[k].out[m[k].nout++] = i;
82 if (k == n) {
83 for (int k = 0; m[i].outc[j][k]; k++)
84 m[n].s[k] = m[i].outc[j][k];
85 n++;
86 }
87 }
88 }
89
90 for (int t = 1; t < n; t++)
91 if (flowatmost(0, t, 3)) nother++;
92
93 printf("%d (%d %d)\n", nother * (n-nother), nother, n-nother);
94 return 0;
95}

Generated with cgit - Back to sebastiano.tronto.net