/* Problem H: Sorting Slides * Author: Mark Dettinger * * Algorithm: * 1.) Construct the following graph: 1 source node, n nodes for the slides, * n nodes for the numbers, 1 sink. Edges from the source to each slide, * from the slides to the possible numbers and from each number to the sink. * 2.) While there exists a path from the source to the sink, flip the direction * of the edges along this path. (This will work exactly n times.) * 3.) You now have found one possible matching: From each number there is an edge * to its slide. Now output all pairs (slide,number) with the following property: * Starting from the slide, the graph should contain no cycle. (If there is * a cycle, it means that there exists a matching where the slide has written * an other number on it.) */ #include #include #define WHITE 0 #define GRAY 1 #define BLACK 2 typedef struct { int left,right,top,bottom; } slide; typedef struct { int x,y; } point; FILE *input; int heap=0; int n; slide s[32]; point p[32]; int a[64][64]; int color[64]; int source,sink; int read_case() { int i; fscanf(input,"%d",&n); if (n==0) return 0; for (i=0; is.left && p.xs.top && p.y0) return 1; if (color[node]!=WHITE) return 0; color[node] = GRAY; for (i=0; i<=sink; i++) if (a[node][i]) if (visit(i,dest,pathlength+1)) { a[i][node] = 1; a[node][i] = 0; return 1; } color[node] = BLACK; return 0; } void print_graph() { int i,j; for (i=0; i<=sink; i++) { printf("%d: ",i); for (j=0; j<=sink; j++) if (a[i][j]) printf("%d ",j); printf("\n"); } } void solve_case() { int i,j,num_edges,pairs; printf("Heap %d\n",++heap); /* construct bipartite graph where nodes 0..n-1 correspond to the numbers and * nodes n..2n-1 correspond to the slides */ source = 2*n; sink = 2*n+1; /* 1. init empty graph */ for (i=0; i<=sink; i++) for (j=0; j<=sink; j++) a[i][j] = 0; /* 2. add edges */ for (i=0; i