#include #include #include #define NEK 1000000000 int d[10002]; int p[10002]; int hash[11000]; struct tab { int uod, udo, del; } tb[50002]; int fronta[100000]; int frend; int frbeg; int N,M,S,C; int qcmp(const void *a, const void *b) { int *x= (int*)a, *y=(int*)b; if(d[*x] < d[*y]) return -1; if(d[*x] > d[*y]) return 1; return 0; } void priority() { for(int i=0; ifrbeg) && (d[fronta[i-1]] > d[u]) ) { fronta[i] = fronta[i-1]; fronta[i-1] = u; } } void fixpri(int x) { int tmp; while( (x>frbeg) && (d[fronta[x-1]] > d[fronta[x]]) ) { tmp = fronta[x-1]; fronta[x-1] = fronta[x]; fronta[x] = tmp; x--; } } int dequeue(void) { int x = fronta[frbeg]; frbeg++; return x; } bool isempty(void) { return frbeg == frend; } 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) { int ww = w(u,v); if( d[v] > (d[u]+ww) ) { d[v] = d[u] + ww; 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 1; return 0; } bool closed[10001]; int main(void) { d[10001] = NEK+1; 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); } if(S == C) { printf("0\n"); continue; } //sort qsort(&tb[1], M, sizeof(tab), cmp); //make hash makehash(); //b-f init_paths(); init_queue(); for(int i= 1; i<=N; i++) { enqueue(i); closed[i] = false; } priority(); int u,z; while( !isempty() && !closed[C]) { u = dequeue(); closed[u] = true; if(u == C) break; z = hash[u]; while(tb[z].uod == u) { if(!closed[tb[z].udo]) relax(u,tb[z].udo); z++; } priority(); } printf("%d\n",d[C]); } while (1); }