/* * Walk in the woods * EC/NE/GNY regional * John Buck, Oct 3, 2023 */ #include #include #include //#define DEBUG #define MAX_INTERSECTIONS 2500 #define MAX_PATHS 2500 enum EDir { NORTH = 0, EAST, SOUTH, WEST, NEDIR }; /* Opposite Dirs */ int OppDir[NEDIR] = { SOUTH, /* If came from north, go south */ WEST, /* If came from south, go north */ NORTH, /* If came from EAST, go west */ EAST /* If came from WEST, go east */ }; const char *szDirs = "NESW"; struct SIntersection; struct SDest { SIntersection *pInt; int nWeight; }; struct SIntersection { int x; int y; int nbranch; int nInt; // debugging SDest dest[NEDIR]; } intsect[MAX_INTERSECTIONS+1]; int m, n, i, j, k, s; char dir[10]; int MapDir(char c) { switch(c){ case 'N': return(NORTH); break; case 'S': return(SOUTH); break; case 'E': return(EAST); break; case 'W': return(WEST); break; } return(-1); } int main() { int in, i1, i2, nw, ubx = 0, uby = 0, ndir, odir, ebr; SIntersection *p1, *p2; scanf("%d %d", &(n), &(m)); #ifdef DEBUG fprintf(stderr, "n=%d m=%d\n", n, m); #endif for(in = 1; in <= n; in++){ scanf("%d %d", &(intsect[in].x), &(intsect[in].y)); #ifdef DEBUG fprintf(stderr, "Int %d: x=%d y=%d\n", in, intsect[in].x, intsect[in].y); #endif intsect[in].nInt = in; if(ubx < intsect[in].x){ ubx = intsect[in].x; } if(uby < intsect[in].y){ uby = intsect[in].y; } } #ifdef DEBUG fprintf(stderr, "upper bounds: x=%d y=%d\n", ubx, uby); #endif for(in = 1; in <= m; in++){ scanf("%d %d %d", &(i1), &(i2), &(nw)); p1 = &(intsect[i1]); p2 = &(intsect[i2]); p1->nbranch++; p2->nbranch++; if(p1->x == p2->x){ if(p1->y < p2->y){ /* p1 is S of p2 */ p1->dest[NORTH].pInt = p2; p1->dest[NORTH].nWeight = nw; p2->dest[SOUTH].pInt = p1; p2->dest[SOUTH].nWeight = nw; #ifdef DEBUG fprintf(stderr, "Int %d(%d,%d) is S of Int %d(%d,%d) (Int %d is N of Int %d) Weight: %d\n", i1, p1->x, p1->y, i2, p2->x, p2->y, i2, i1, nw); #endif } else { /* p1 is N of p2 */ p1->dest[SOUTH].pInt = p2; p1->dest[SOUTH].nWeight = nw; p2->dest[NORTH].pInt = p1; p2->dest[NORTH].nWeight = nw; #ifdef DEBUG fprintf(stderr, "Int %d(%d,%d) is N of Int %d(%d,%d) (Int %d is S of Int %d) Weight: %d\n", i1, p1->x, p1->y, i2, p2->x, p2->y, i2, i1, nw); #endif } } else { if(p1->x < p2->x){ /* p1 is W of p2 */ p1->dest[EAST].pInt = p2; p1->dest[EAST].nWeight = nw; p2->dest[WEST].pInt = p1; p2->dest[WEST].nWeight = nw; #ifdef DEBUG fprintf(stderr, "Int %d(%d,%d) is W of Int %d(%d,%d) (Int %d is E of Int %d) Weight: %d\n", i1, p1->x, p1->y, i2, p2->x, p2->y, i2, i1, nw); #endif } else { /* p1 is E of p2 */ p1->dest[WEST].pInt = p2; p1->dest[WEST].nWeight = nw; p2->dest[EAST].pInt = p1; p2->dest[EAST].nWeight = nw; #ifdef DEBUG fprintf(stderr, "Int %d(%d,%d) is E of Int %d(%d,%d) (Int %d is W of Int %d) Weight: %d\n", i1, p1->x, p1->y, i2, p2->x, p2->y, i2, i1, nw); #endif } } } scanf("%d %s", &(s), &(dir[0])); p1 = &(intsect[s]); ndir = MapDir(dir[0]); for(;;){ odir = OppDir[ndir]; p2 = p1->dest[ndir].pInt; #ifdef DEBUG fprintf(stderr, "At Int %d (%d,%d) and heading %c to (%d,%d) Weight %d\n", p1->nInt, p1->x, p1->y, szDirs[ndir], p2->x, p2->y, p1->dest[ndir].nWeight); #endif p1->dest[ndir].nWeight--; p2->dest[odir].nWeight--; if(p1->dest[ndir].nWeight == 0){ p2->nbranch--; p1->nbranch--; } /* Number of branches at new node */ ebr = p2->nbranch; /* Subtract off from whence we came, if still active */ if(p2->dest[odir].nWeight > 0){ ebr--; } p1 = p2; /* End of the line - no more branches, or, only branch left is from whence we came */ if(ebr == 0){ break; } /* Compute next node */ switch(ebr){ case 1: for(ndir = NORTH; ndir <= WEST; ndir++){ if(ndir == odir || p1->dest[ndir].nWeight == 0){ continue; } break; } break; case 2: for(ndir = odir + 1; ; ndir++){ if(ndir >= NEDIR){ ndir = NORTH; } if(p1->dest[ndir].nWeight > 0){ break; } } break; case 3: /* Same direction actually - we keep going */ break; } odir = OppDir[ndir]; } printf("%d %d\n", p1->x, p1->y); return(0); }