#include #include #include #define NEK 1000000000 int d[10002]; int p[10002]; int hash[11000]; struct tab { int uod, udo, del; } tb[50002]; int N,M,S,C; int fronta[1000000]; int frbeg, frend; void init_queue(void) { frbeg = frend = 0; } void enqueue(int u) { fronta[frend] = u; frend = (frend+1) % 1000000; } int dequeue(void) { int x = fronta[frbeg]; frbeg = (frbeg+1) % 1000000; return x; } bool isempty(void) { return frend==frbeg; } int w(int, int); void relax_q(int u, int v) { int ww = w(u,v); if( d[v] > (d[u] + ww) ) { d[v] = d[u] + ww; p[v] = u; enqueue(v); } } int w(int u, int v) { int i = hash[u]; while( (tb[i].uod == u) && (tb[i].udo != v) ) i++; return (tb[i].udo == v) ? tb[i].del : NEK; } void init_paths(void) { for(int i=0; i<=N; i++) { d[i] = NEK; p[i] = 0; } d[S] = 0; } void relax(int u, int v) { if( d[v] > (d[u]+w(u,v)) ) { d[v] = d[u] + w(u,v); p[v] = u; } } void makehash(void) { for(int i = M; i>0; i--) { hash[tb[i].uod] = i; } } int cmp(const void *a, const void *b) { if( ((tab*)a)->uod < ((tab*)b)->uod) return -1; if( ((tab*)a)->uod == ((tab*)b)->uod) return 0; return 1; } int main(void) { do { scanf("%d %d %d %d", &N, &M, &S, &C); if( (N | M | S | C) == 0 ) return 0; for(int i=1; i<=M; i++) { scanf("%d %d %d", &tb[i].uod, &tb[i].udo, &tb[i].del); } //sort qsort(&tb[1], M, sizeof(tab), cmp); //make hash makehash(); //b-f init_paths(); init_queue(); enqueue(S); int u,z; while( !isempty() ) { u = dequeue(); z = hash[u]; while(tb[z].uod == u) { relax_q(u,tb[z].udo); z++; } } printf("%d\n",d[C]); } while (1); }