#include "config.h" #include #include #include #include #include #include #include "../algorithm.c" #ifdef HAVE_ZLIB #include gzFile infile; #define BUFFER_SIZE 10000 char buffer[BUFFER_SIZE]; static int myscanf(const char *fmt, ...) { gzgets(infile, buffer, BUFFER_SIZE); va_list args; va_start(args, fmt); int ret = vsscanf(buffer, fmt, args); va_end(args); return ret; } #endif #define CHECK(arg) if(!(arg)){fprintf(stderr, "failed CHECK at line %d: %s\n", __LINE__, #arg); abort();} /* Read multiple testcases from a file. * Each test case consist of: * - one line with N and M, the number of nodes and arcs * - for each arc a line with numbers head, tail, cap and cost, defining the * arc's endpoints and values, * - one line with numbers: amount and best_cost, indicating that we wish to * send amount from node 0 to node 1 with minimum cost, the correct answer * should contain a flow cost equal to best_cost. * * A feasible solution is guaranteed. * The last test case has 0 nodes and should be ignored. */ static int next_bit(s64 x) { int b; for (b = 0; (1LL << b) <= x; b++) ; return b; } static bool solve_case(const tal_t *ctx) { static int c = 0; c++; tal_t *this_ctx = tal(ctx, tal_t); int N_nodes, N_arcs; scanf("%d %d\n", &N_nodes, &N_arcs); printf("Testcase %d\n", c); printf("nodes %d arcs %d\n", N_nodes, N_arcs); if (N_nodes == 0 && N_arcs == 0) goto fail; const int MAX_NODES = N_nodes; const int DUAL_BIT = next_bit(N_arcs-1); const int MAX_ARCS = 1LL << (DUAL_BIT+1); printf("max nodes %d max arcs %d bit %d\n", MAX_NODES, MAX_ARCS, DUAL_BIT); struct graph *graph = graph_new(ctx, MAX_NODES, MAX_ARCS, DUAL_BIT); assert(graph); s64 *capacity = tal_arrz(ctx, s64, MAX_ARCS); s64 *cost = tal_arrz(ctx, s64, MAX_ARCS); for (u32 i = 0; i < N_arcs; i++) { u32 from, to; scanf("%" PRIu32 " %" PRIu32 " %" PRIi64 " %" PRIi64, &from, &to, &capacity[i], &cost[i]); struct arc arc = {.idx = i}; graph_add_arc(graph, arc, node_obj(from), node_obj(to)); struct arc dual = arc_dual(graph, arc); cost[dual.idx] = -cost[i]; } printf("Reading arcs finished\n"); struct node src = {.idx = 0}; struct node dst = {.idx = 1}; s64 amount, best_cost; scanf("%" PRIi64 " %" PRIi64, &amount, &best_cost); bool result = simple_mcf(ctx, graph, src, dst, capacity, amount, cost); assert(result); assert(node_balance(graph, src, capacity) == -amount); assert(node_balance(graph, dst, capacity) == amount); for (u32 i = 2; i < N_nodes; i++) assert(node_balance(graph, node_obj(i), capacity) == 0); const s64 total_cost = flow_cost(graph, capacity, cost); assert(total_cost == best_cost); tal_free(this_ctx); return true; fail: tal_free(this_ctx); return false; } int main(int argc, char *argv[]) { #ifdef HAVE_ZLIB common_setup(argv[0]); infile = gzopen("plugins/askrene/test/data/linear_mcf.gz", "r"); CHECK(infile); const tal_t *ctx = tal(NULL, tal_t); CHECK(ctx); /* One test case after another. The last test case has N number of nodes * and arcs equal to 0 and must be ignored. */ while (solve_case(ctx)) ; ctx = tal_free(ctx); gzclose(infile); common_shutdown(); return 0; #else return 0; #endif }