// Dijkstra # include <iostream> # include <cstdio> # include <cstdlib> # include <cstring> # include <string> # define INF 0x3f3f3fusing namespace std; struct node {int d, p;} mat [1005] [1005]; int main () {int x, y, n, m, a, B, s, t, i, j, k, d [1005], p [1005], minsd, minsp, visited [1005]; while (scanf ("% d", & n, & m )! = EOF & (n! = 0 | m! = 0) {memset (visited, 0, sizeof (visited); for (I = 1; I <= n; I ++) for (j = 1; j <= n; j ++) {mat [I] [j]. d = INF; mat [I] [j]. p = INF ;}// initialization matrix for (I = 1; I <= m; I ++) {cin> a> B> x> y; // Note: remove the duplicate edge. Here, WA two if (x <mat [a] [B]. d | (x = mat [a] [B]. d & y <mat [a] [B]. p) {mat [a] [B]. d = mat [B] [a]. d = x; mat [a] [B]. p = mat [B] [a]. p = y ;}} cin >>s> t; visited [s] = 1, d [s] = 0; for (I = 1; I <= n; I ++) {d [I] = mat [s] [I]. d; p [I] = mat [s] [I]. p ;}// distance initialization for (I = 1; I <n; I ++) {minsp = minsd = INF; for (j = 1; j <= n; j ++) if (! Visited [j] & minsd> d [j]) {minsd = d [j]; minsp = p [j]; k = j ;} // find the vertex with the smallest edge. Like prim, greedy visited [k] = 1; for (j = 1; j <= n; j ++) if (! Visited [j] & mat [k] [j]. d! = INF) {if (d [k] + mat [k] [j]. d <d [j]) {d [j] = d [k] + mat [k] [j]. d; p [j] = p [k] + mat [k] [j]. p;} else if (d [k] + mat [k] [j]. d = d [j] & p [k] + mat [k] [j]. p <p [j]) p [j] = p [k] + mat [k] [j]. p; else;} // The distance to which the update will arrive. Because the distance is not limited, so we need to judge twice} cout <d [t] <"" <p [t] <endl ;}return 0 ;}