#include "faruk.h" #ifndef INT_MAX #define INT_MAX 2147483647 #endif #define unseen (INT_MAX - 2) #define BLUE 0 #define PURPLE 1 FILE *ifp, *ofp; /************************************** init declarations ***************/ struct node { short v ; /* name of the vertex */ short w ; /* weight */ struct node *next; }; short V, E; /* number of Vertices and Edges * * V <= 300 E <= 14000 */ short from,to; struct node **adj; struct node *t, *z; struct lighttype { short initial; /* initial colour of vertex */ short fp; /* first period in seconds */ short blue; /* period of blue in seconds */ short purple; /* period of purple in seconds */ short icp; /* initial color period in sec. */ short scp; /* secondary color period , * * needed in det_color() */ }; struct lighttype *light; long *val; /* dad and val arrays */ short *dad; short *resar; /***************************************** determining priorities */ short det_color(short c, long t) { if (t < light[c].fp) return (light[c].initial); if (((t - light[c].fp) % (light[c].blue + light[c].purple)) < light[c].scp) return ((light[c].initial + 1) % 2); /* return secondary colour */ return light[c].initial; } void det_times(short v, short c, long t, short *mt) { if (t < light[v].fp) { mt[0] = light[v].fp - t; mt[1] = mt[0] + light[v].scp; mt[2] = mt[1] + light[v].icp; } else if (c == light[v].initial) { mt[0] = (light[v].scp + light[v].icp) - (t - light[v].fp) % (light[v].scp + light[v].icp); mt[1] = mt[0] + light[v].scp; mt[2] = mt[1] + light[v].icp; } else { mt[0] = light[v].scp - (t - light[v].fp) % (light[v].scp + light[v].icp); mt[1] = mt[0] + light[v].icp; mt[2] = mt[1] + light[v].scp; } } #define MIN(x,y) ((x v) { a[k] = v; return 1; } return 0; } short f_remove() { register short i; short c; long t = unseen + 1; for(i = 1; i <= V; i++) if ( (a[i] != 0) && (a[i] < t) ) { c = i; t = a[i]; } N--; a[c] = 0; return c; } /***************************************** input functions */ void adjlist() { register short j; short x, y, weight; z=(struct node *) f_malloc(sizeof *z); z->next=z; for(j=1; j<=V; j++) adj[j]=z; for(j=1; j<=E; j++) { fscanf(ifp,"%hd %hd %hd\n", &x, &y, &weight); if (!((light[x].initial != light[y].initial) && (light[x].fp == light[y].fp) && (light[x].blue == light[y].purple) && (light[x].purple == light[y].blue))) { t=(struct node *) f_malloc(sizeof *t); t->v=x; t->w=weight; t->next=adj[y]; adj[y]=t; t=(struct node *) f_malloc(sizeof *t); t->v=y; t->w=weight; t->next=adj[x]; adj[x]=t; } } } void get_vertices() { char state; register short i; for (i = 1; i <= V; i++) { fscanf(ifp,"%c %hd %hd %hd\n", &state, &light[i].fp, &light[i].blue, &light[i].purple); light[i].initial = (state == 'B') ? BLUE : PURPLE; light[i].scp = (state == 'B') ? light[i].purple : light[i].blue; light[i].icp = (state == 'P') ? light[i].purple : light[i].blue; } } void get_input() { register short i; ifp = f_fopen("LIGHTS.INP","r"); fscanf(ifp,"%hd %hd\n",&from,&to); fscanf(ifp,"%hd %hd\n",&V,&E); dad = (short *) f_malloc ((V+1) * sizeof (short)); val = (long *) f_malloc ((V+1) * sizeof (long)); for (i = 1; i <= V; i++) { dad[i] = 0; val[i] = 0; } light = (struct lighttype *) f_malloc ((V+1) * sizeof (struct lighttype)); get_vertices(); adj = (struct node **) f_malloc ((V+1) * sizeof (struct node *)); adjlist(); fclose(ifp); } /***************************************** find shortest path */ void visit(short k) { struct node *t; if (f_update(k, unseen) != 0) dad[k] = 0; while (!f_empty()) { k = f_remove(); val[k] = -val[k]; if (val[k] == unseen) val[k] = 0; for (t = adj[k]; t != z; t = t->next) if (val[t->v] < 0) if (f_update(t->v, prcalc(k,t->v,val[k]) + val[k] + t->w)) { val[t->v] = -(prcalc(k,t->v,val[k]) + val[k] + t->w); dad[t->v] = k; } } } void allsp() { register short k; f_initialize(); for (k = 1; k <= V; k++) val[k] = -unseen; if (val[from] == -unseen) visit(from); for (k = 1; k <= V; k++) if ((val[k] == -unseen) && (k != from)) visit(k); } void putitout() { short i = 0, j, x; resar = (short *) f_malloc((V+1) * sizeof(short)); for (i = 0; i <= V; i++) resar[i] = 0; i = 0; resar[++i]=to; x=dad[to]; do { resar[++i] = x; x=dad[x]; } while (x != 0); ofp = f_fopen("LIGHTS.OUT","w"); if (resar[i] != from) { fprintf(stderr, "no solution\n"); exit(-1); } fprintf(ofp,"%ld\n",val[to]); for (j = i; j >= 1; j--) fprintf(ofp,"%d ",resar[j]); fputs("\n",ofp); fclose(ofp); } /***************************************** main */ extern long memory_allocated; int main() { get_input(); allsp(); putitout(); /* printf("%ld\n",memory_allocated);*/ return 0; }