void constructGraph(int internalDegree, int depth){ int i, j, k; int minLeaf, maxLeaf; GRAPH graph; ADJACENCY adj; prepareGraph(graph, adj, getOrder(internalDegree, depth)); if(depth==0){ writeMultiCode(graph, adj, stdout); return; } for(i = 0; i < internalDegree; i++){ addEdge(graph, adj, 1, 2 + i); } minLeaf = 2; maxLeaf = 1 + internalDegree; for(i = 1; i < depth; i++){ int newLeaf = maxLeaf + 1; for(j = minLeaf; j <= maxLeaf; j++){ for(k = 0; k < internalDegree - 1; k++){ addEdge(graph, adj, j, newLeaf); newLeaf++; } } minLeaf = maxLeaf + 1; maxLeaf = newLeaf - 1; } writeMultiCode(graph, adj, stdout); }
void handleBiconnectedComponent(GRAPH graph, ADJACENCY adj, int uEnd, int vEnd){ int i, u, v; GRAPH biconnectedGraph; ADJACENCY biconnectedAdj; int newLabel[MAXN+1]; for(i = 0; i < MAXN; i++){ newLabel[i] = 0; } //we will use i to relabel the vertices i = 0; //just prepare the graph for a large enough number of vertices prepareGraph(biconnectedGraph, biconnectedAdj, graph[0][0]); do { POP_EDGE(u,v); if(!newLabel[u]){ i++; newLabel[u] = i; } if(!newLabel[v]){ i++; newLabel[v] = i; } //no extra check needed since each edge is only once in the stack addEdge(biconnectedGraph, biconnectedAdj, newLabel[u], newLabel[v]); } while(uEnd != u || vEnd != v); //set the connect number of vertices biconnectedGraph[0][0] = i; writeMultiCode(biconnectedGraph, biconnectedAdj, stdout); }
/* * Constructs the cycle graph with the specified number of vertices. * The graph is output in multi_code format. */ void constructGraph(int order){ int i; GRAPH graph; ADJACENCY adj; prepareGraph(graph, adj, order); for(i = 1; i <= order; i++){ addEdge(graph, adj, i, (i%order)+1); } writeMultiCode(graph, adj, stdout); }
void codetograph(char *code, GRAPH graph, ADJACENCY adj) { char i, v = 1, w; prepareGraph(graph, adj, n); for (i = n * k / 2; i > 0; i--) { w = *code; while (adj[v] == k) { v++; } addEdge(graph, adj, v, w); code++; } }
void constructCorona(GRAPH graph, ADJACENCY adj, GRAPH coronaGraph, ADJACENCY coronaAdj){ int i, j; int order = graph[0][0]; prepareGraph(coronaGraph, coronaAdj, order*2); for(i=1; i<=order; i++){ for(j=0; j<adj[i]; j++){ if(i < graph[i][j]){ addEdge(coronaGraph, coronaAdj, i, graph[i][j]); } } addEdge(coronaGraph, coronaAdj, i, i + order); } }
/* * Constructs the generalized Petersengraph G(n,k). * The graph is output in multi_code format. */ void constructGraph(int n, int k){ int i; GRAPH graph; ADJACENCY adj; prepareGraph(graph, adj, 2*n); for(i = 1; i <= n; i++){ addEdge(graph, adj, i, (i%n)+1); addEdge(graph, adj, i, i + n); addEdge(graph, adj, i+n, ((i-1+k)%n) + n + 1); } writeMultiCode(graph, adj, stdout); }
/* * Constructs a fat K_n with the specified number of vertices and edge * multiplicity. The graph is output in multi_code format. */ void constructGraph(int vertices, int edgeMultiplicity){ int i, j, k; GRAPH graph; ADJACENCY adj; prepareGraph(graph, adj, vertices); for(i = 1; i < vertices; i++){ for(j = i+1; j <= vertices; j++){ for(k = 0; k < edgeMultiplicity; k++){ addEdge(graph, adj, i, j); } } } writeMultiCode(graph, adj, stdout); }
void decodeMultiCode(unsigned short* code, int length, GRAPH graph, ADJACENCY adj, int *order) { int i, currentVertex; unsigned short vertexCount; *order = vertexCount = code[0]; prepareGraph(graph, adj, vertexCount); //go through code and add edges currentVertex = 1; for (i = 1; i < length; i++) { if (code[i] == 0) { currentVertex++; } else { addEdge(graph, adj, currentVertex, (int) code[i], FALSE); if ((adj[code[i]] > MAXVAL) || (adj[currentVertex] > MAXVAL)) { fprintf(stderr, "MAXVAL too small (%d)!\n", MAXVAL); exit(0); } } } }
template <typename captype, typename tcaptype, typename flowtype> flowtype IBFSGraph<captype, tcaptype, flowtype>::maxflow() { node *i, *j, *i_tmp, *prevSrc, *prevSink; arc *a, *a_end, *a_tmp; AugmentationInfo augInfo; prepareGraph(); #ifdef STATS numAugs = 0; numOrphans = 0; grownSinkTree = 0; grownSourceTree = 0; numPushes = 0; orphanArcs1 = 0; orphanArcs2 = 0; orphanArcs3 = 0; growthArcs = 0; skippedGrowth = 0; numOrphans0 = 0; numOrphans1 = 0; numOrphans2 = 0; augLenMin = 999999; augLenMax = 0; #endif // // init // orphanFirst = END_OF_ORPHANS; activeFirst1 = END_OF_LIST_NODE; activeLevel = 1; for (i=nodes; i<nodeLast; i++) { i->nextActive = NULL; i->firstSon = NULL; if (i->terminalCap == 0) { i->parent = NULL; } else { i->parent = TERMINAL; if (i->terminalCap > 0) { i->label = 1; SET_ACTIVE(i); } else { i->label = -1; SET_ACTIVE(i); } } } activeFirst0 = activeFirst1; activeFirst1 = END_OF_LIST_NODE; // // growth + augment // prevSrc = NULL; prevSink = NULL; augInfo.flowDeficit = 0; augInfo.flowExcess = 0; while (activeFirst0 != END_OF_LIST_NODE) { // // BFS level // while (activeFirst0 != END_OF_LIST_NODE) { /* i = active_src_first0; while (i->nextActive != END_OF_LIST_NODE) { if (i->parent && i->nextActive->parent && i->label > 0 && i->label != activeLevel_src && i->label != activeLevel_src+1) { i = active_src_first0; printf("flow=%d, active_label=%d, src active ", flow, activeLevel_src); while (i != END_OF_LIST_NODE) { if (i->parent && (i->nextActive == END_OF_LIST_NODE || i->nextActive->parent == NULL || i->label != i->nextActive->label)) { printf("%d ", i->label); } i = i->nextActive; } printf("\n"); break; } i = i->nextActive; } */ i = activeFirst0; activeFirst0 = i->nextActive; i->nextActive = NULL; if (i->parent == NULL) { #ifdef STATS skippedGrowth++; #endif continue; } //if (ABS(i->label) != activeLevel && // ABS(i->label) != (activeLevel+1)) //{ //#ifdef FLOATS // printf("ERROR, flow=%f, label=%d, active_label=%d\n", // flow, i->label, activeLevel); //#else // printf("ERROR, flow=%d, label=%d, active_label=%d\n", // flow, i->label, activeLevel); //#endif // exit(1); //} if (i->label > 0) { // // GROWTH SRC // if (i->label != activeLevel) { #ifdef STATS skippedGrowth++; #endif SET_ACTIVE(i); continue; } #ifdef STATS grownSourceTree++; #endif a_end = (i+1)->firstArc; for (a=i->firstArc; a != a_end; a++) { #ifdef STATS growthArcs++; #endif if (a->rCap != 0) { j = a->head; if (j->parent == NULL) { j->label = i->label+1; j->parent = a->sister; j->nextSibling = NODE_PTR_TO_INDEX(i->firstSon); i->firstSon = j; SET_ACTIVE(j); } else if (j->label < 0) { i->nextActive = activeFirst0; activeFirst0 = i; if (prevSrc != i) { augInfo.remainingExcess = 0; if (augInfo.flowExcess != 0) { i_tmp = prevSrc; for (; ; i_tmp=a_tmp->head) { a_tmp = i_tmp->parent; if (a_tmp == TERMINAL) break; a_tmp->rCap += augInfo.flowExcess; a_tmp->sister->sister_rCap = 1; a_tmp->sister->rCap -= augInfo.flowExcess; } i_tmp->terminalCap -= augInfo.flowExcess; augInfo.flowExcess = 0; } } if (prevSrc != i || prevSink != j) { augInfo.remainingDeficit = 0; if (augInfo.flowDeficit != 0) { i_tmp = prevSink; for (; ; i_tmp=a_tmp->head) { a_tmp = i_tmp->parent; if (a_tmp == TERMINAL) break; a_tmp->sister->rCap += augInfo.flowDeficit; a_tmp->sister_rCap = 1; a_tmp->rCap -= augInfo.flowDeficit; } i_tmp->terminalCap += augInfo.flowDeficit; augInfo.flowDeficit = 0; } } augment(a, &augInfo); prevSrc = i; prevSink = j; break; } } } } else { // // GROWTH SINK // if (-(i->label) != activeLevel) { #ifdef STATS skippedGrowth++; #endif SET_ACTIVE(i); continue; } #ifdef STATS grownSinkTree++; #endif a_end = (i+1)->firstArc; for (a=i->firstArc; a != a_end; a++) { #ifdef STATS growthArcs++; #endif if (a->sister_rCap != 0) { j = a->head; if (j->parent == NULL) { j->label = i->label-1; j->parent = a->sister; j->nextSibling = NODE_PTR_TO_INDEX(i->firstSon); i->firstSon = j; SET_ACTIVE(j); } else if (j->label > 0) { i->nextActive = activeFirst0; activeFirst0 = i; if (prevSink != i) { augInfo.remainingDeficit = 0; if (augInfo.flowDeficit != 0) { i_tmp = prevSink; for (; ; i_tmp=a_tmp->head) { a_tmp = i_tmp->parent; if (a_tmp == TERMINAL) break; a_tmp->sister->rCap += augInfo.flowDeficit; a_tmp->sister_rCap = 1; a_tmp->rCap -= augInfo.flowDeficit; } i_tmp->terminalCap += augInfo.flowDeficit; augInfo.flowDeficit = 0; } } if (prevSink != i || prevSrc != j) { augInfo.remainingExcess = 0; if (augInfo.flowExcess != 0) { i_tmp = prevSrc; for (; ; i_tmp=a_tmp->head) { a_tmp = i_tmp->parent; if (a_tmp == TERMINAL) break; a_tmp->rCap += augInfo.flowExcess; a_tmp->sister->sister_rCap = 1; a_tmp->sister->rCap -= augInfo.flowExcess; } i_tmp->terminalCap -= augInfo.flowExcess; augInfo.flowExcess = 0; } } augment(a->sister, &augInfo); prevSrc = j; prevSink = i; break; } } } } } augInfo.remainingDeficit = 0; if (augInfo.flowDeficit != 0) { i_tmp = prevSink; for (; ; i_tmp=a_tmp->head) { a_tmp = i_tmp->parent; if (a_tmp == TERMINAL) break; a_tmp->sister->rCap += augInfo.flowDeficit; a_tmp->sister_rCap = 1; a_tmp->rCap -= augInfo.flowDeficit; } i_tmp->terminalCap += augInfo.flowDeficit; augInfo.flowDeficit = 0; prevSink = NULL; } augInfo.remainingExcess = 0; if (augInfo.flowExcess != 0) { i_tmp = prevSrc; for (; ; i_tmp=a_tmp->head) { a_tmp = i_tmp->parent; if (a_tmp == TERMINAL) break; a_tmp->rCap += augInfo.flowExcess; a_tmp->sister->sister_rCap = 1; a_tmp->sister->rCap -= augInfo.flowExcess; } i_tmp->terminalCap -= augInfo.flowExcess; augInfo.flowExcess = 0; prevSrc = NULL; } // // switch to next level // #ifdef COUNT_RELABELS for (int k=0; k<scanIndices.size(); k++) { total++; if (scans[scanIndices[k]] <= 10) { counts[scans[scanIndices[k]]-1]++; } } #endif activeFirst0 = activeFirst1; activeFirst1 = END_OF_LIST_NODE; activeLevel++; } return flow; }