int solve() { int i, j; for (i = 0; i < n*2; i+=2) { if (v[i].tf == 0 && v[i^1].tf == 0) { ST_RESET(); if(dfs(i) == 0) { /* restore previos dfs */ while (!ST_IS_EMPTY()) { ST_POP(j); v[j].tf = 0; } /* try another path */ if(dfs(i^1) == 0) return 0; } } } return 1; }
static struct i_bitmap * i_flood_fill_low(i_img *im,i_img_dim seedx,i_img_dim seedy, i_img_dim *bxminp, i_img_dim *bxmaxp, i_img_dim *byminp, i_img_dim *bymaxp, i_color const *seed, ff_cmpfunc cmpfunc) { i_img_dim ltx, rtx; i_img_dim tx = 0; i_img_dim bxmin = seedx; i_img_dim bxmax = seedx; i_img_dim bymin = seedy; i_img_dim bymax = seedy; struct llist *st; struct i_bitmap *btm; int channels; i_img_dim xsize,ysize; i_color cval; channels = im->channels; xsize = im->xsize; ysize = im->ysize; btm = btm_new(xsize, ysize); st = llist_new(100, sizeof(struct stack_element*)); /* Find the starting span and fill it */ ltx = i_lspan(im, seedx, seedy, seed, cmpfunc); rtx = i_rspan(im, seedx, seedy, seed, cmpfunc); for(tx=ltx; tx<=rtx; tx++) SET(tx, seedy); bxmin = ltx; bxmax = rtx; ST_PUSH(ltx, rtx, ltx, rtx, seedy+1, 1); ST_PUSH(ltx, rtx, ltx, rtx, seedy-1, -1); while(st->count) { /* Stack variables */ i_img_dim lx,rx; i_img_dim dadLx,dadRx; i_img_dim y; int direction; i_img_dim x; int wasIn=0; ST_POP(); /* sets lx, rx, dadLx, dadRx, y, direction */ if (y<0 || y>ysize-1) continue; if (bymin > y) bymin=y; /* in the worst case an extra line */ if (bymax < y) bymax=y; x = lx+1; if ( lx >= 0 && (wasIn = INSIDE(lx, y, seed)) ) { SET(lx, y); lx--; while(lx >= 0 && INSIDE(lx, y, seed)) { SET(lx,y); lx--; } } if (bxmin > lx) bxmin = lx; while(x <= xsize-1) { /* printf("x=%d\n",x); */ if (wasIn) { if (INSIDE(x, y, seed)) { /* case 1: was inside, am still inside */ SET(x,y); } else { /* case 2: was inside, am no longer inside: just found the right edge of a span */ ST_STACK(direction, dadLx, dadRx, lx, (x-1), y); if (bxmax < x) bxmax = x; wasIn=0; } } else { if (x > rx) goto EXT; if (INSIDE(x, y, seed)) { SET(x, y); /* case 3: Wasn't inside, am now: just found the start of a new run */ wasIn = 1; lx = x; } else { /* case 4: Wasn't inside, still isn't */ } } x++; } EXT: /* out of loop */ if (wasIn) { /* hit an edge of the frame buffer while inside a run */ ST_STACK(direction, dadLx, dadRx, lx, (x-1), y); if (bxmax < x) bxmax = x; } } llist_destroy(st); *bxminp = bxmin; *bxmaxp = bxmax; *byminp = bymin; *bymaxp = bymax; return btm; }