4 /* https://en.wikipedia.org/wiki/Stoer%E2%80%93Wagner_algorithm
5 * Modified by the fact that we KNOW mincut is 3, and we instead
6 * want the count of nodes on each side of the cut. So, instead
7 * of running the algorithm to the end, we track an additional
8 * node-count metric, and stop when we hit the desired mincount.
11 #define maxn 1500 /* 1484 in my input */
12 int map
[26*26*26]; /* map input 3-alpha into node number */
13 int edge
[maxn
][maxn
]; /* weighted adjacency matrix */
14 int dist
[maxn
]; /* weight of each node */
15 int count
[maxn
]; /* number of nodes merged together */
16 bool vis
[maxn
]; /* true if vertex visited */
17 bool bin
[maxn
]; /* true for vertex deleted by merging */
18 int n
; /* vertex count; for convenience first vertex is 1 */
20 int contract(int *s
, int *t
)
22 int i
, j
, k
, mincut
, maxc
;
23 for (i
= 1; i
<= n
; i
++) {
26 for (i
= 1; i
<= n
; i
++) {
28 for (j
= 1; j
<= n
; j
++)
29 if (!bin
[j
] && !vis
[j
] && dist
[j
] > maxc
) {
30 k
= j
; maxc
= dist
[j
];
37 for (j
= 1; j
<= n
; j
++)
38 if (!bin
[j
] && !vis
[j
])
39 dist
[j
] += edge
[k
][j
];
44 int stoer_wagner(void)
47 for (i
= 1; i
< n
; i
++) {
48 ans
= contract(&s
, &t
);
51 printf("%d %d %d %d\n", s
, t
, count
[s
], count
[t
]);
52 ans
= count
[s
] + count
[t
];
53 return ans
* (n
- ans
);
56 for (j
= 1; j
<= n
; j
++)
58 edge
[s
][j
] = (edge
[j
][s
] += edge
[j
][t
]);
63 int value(char name
[3]) {
64 int v
= (name
[0]-'a')*26*26 + (name
[1]-'a')*26 + name
[2]-'a';
72 int main(int argc
, char **argv
)
79 printf("usage: %s day25.input\n", argv
[0]);
82 in
= fopen(argv
[1], "r");
84 printf("failure to open file\n");
87 while (fscanf(in
, "%3c:", name
) == 1) {
89 while (getc(in
) == ' ') {
90 fscanf(in
, "%3c", name
);
92 edge
[a
][b
] = edge
[b
][a
] = 1;
95 printf("%d\n", stoer_wagner());