[Cpp]
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Define NIL 100000
Struct Node
{
Int d; // the shortest path length of the record
Int m; // minimum expense of the record
Int pre; // record Precursor
Int flag; // The set to which the flag belongs.
} Node [2, 1001];
/*
Initialize the Source Vertex to 0.
@ Param n number of nodes
@ Param s source point
*/
Int init_#path_source (int n, int s)
{
Int I = 1;
For (I = 1; I <= n; ++ I)
{
Node [I]. d = NIL; // start to set the shortest path to infinity.
Node [I]. m = NIL; // The minimum cost is infinite.
Node [I]. flag = 0; // The set of 0
Node [I]. pre = 0; // The precursor is 0.
}
Node [s]. d = 0; // the Shortest Path of the source node is set to 0.
Node [s]. m = 0; // The minimum cost is set to 0.
Return 1;
}
/* Relaxation operation
* @ Param u path start point
* @ Param v path end point
* @ Param gp Path Graph
* @ Param gm expense chart
*/
Int relax (int u, int v, int ** gp, int ** gm)
{
If (node [v]. d> node [u]. d + gp [u] [v]) // loosen the path
{
Node [v]. d = node [u]. d + gp [u] [v];
Node [v]. m = node [u]. m + gm [u] [v];
Node [v]. pre = u;
}
Else if (node [v]. d = node [u]. d + gp [u] [v]) // relax the cost
{
If (node [v]. m> = node [u]. m + gm [u] [v])
{
Node [v]. d = node [u]. d + gp [u] [v];
Node [v]. m = node [u]. m + gm [u] [v];
Node [v]. pre = u;
}
}
Return 1;
}
/* Apply for a two-dimensional array space with the size of n * n
@ Param n size of the two-dimensional array space
@ Result returns a (n + 1) * (n + 1) two-dimensional array with subscripts starting from 1 to n.
*/
Int ** apply_malloc (int n)
{
Int ** p;
Int I;
P = (int **) malloc (sizeof (int) * (n + 1 ));
For (I = 0; I <= n; ++ I)
{
P [I] = (int *) malloc (sizeof (int) * (n + 1 ));
}
Return p;
}
/* Initialize a two-dimensional array
@ Param gp: storage path weight
@ Param gm: storage cost weight
*/
Int init (int ** gp, int ** gm, int n)
{
Int I = 1, j = 1;
For (I = 1; I <= n; ++ I)
{
For (j = I; j <= n; ++ j)
{
Gp [I] [j] = NIL;
Gp [j] [I] = NIL;
Gm [I] [j] = NIL;
Gm [j] [I] = NIL;
}
}
Return 1;
}
/**
Dijkstra Algorithm
*/
Int dijkstra (int ** gp, int ** gm, int s, int n)
{
Int flag = n;
Int index = 0;
Int I, j, min;
Init_appspath_source (n, s );
While (flag --)
{
/* Find the smallest node on the upper bound of the path in set 0 */
For (I = 1; I <= n; ++ I)
{
If (node [I]. flag = 0)
{
Min = node [I]. d;
Index = I;
Break;
}
}
For (++ I; I <= n; ++ I)
{
If (node [I]. flag = 0 & min> node [I]. d)
{
Min = node [I]. d;
Index = I;
}
}
/* Add the vertex to the 1 Set */
Node [index]. flag = 1;
/* Perform the relaxation operation on each path starting from this point */
For (j = 1; j <= n; ++ j)
{
If (node [j]. flag = 0 & gp [index] [j]! = NIL)
{
Relax (index, j, gp, gm );
}
}
}
Return 1;
}
/* Print a two-dimensional array */
Int printf_array_2 (int ** array, int n)
{
Int I, j;
For (I = 1; I <= n; ++ I)
{
For (j = 1; j <= n; ++ j)
{
Printf ("% d \ t", array [I] [j]);
}
Printf ("\ n ");
}
Return 1;
}
/* Main method */
Int main ()
{
Int n, m, a, B, p, q, I, s, e;
Int ** gp, ** gm;
/* Enter the number of nodes ,*/
Scanf ("% d", & n, & m );
While (n | m)
{
/* Apply for two-dimensional array spaces, one storing path weights and one storing cost weights */
Gp = apply_malloc (n );
Gm = apply_malloc (n );
/* Initialize the orders table */
Init (gp, gm, n );
For (I = 1; I <= m; ++ I)
{
/* Input path and cost */
Scanf ("% d", & a, & B, & p, & q );
/* Solve the problem of multiple paths. Calculate the path with the smallest weight value */
If (gp [a] [B]> p)
{
Gp [a] [B] = p;
Gm [a] [B] = q;
Gp [B] [a] = p;
Gm [B] [a] = q;
}
/* Solve the problem that multiple paths have the same weight, and calculate with the minimum cost */
Else if (gp [a] [B] = p & gm [a] [B]> q)
{
Gm [a] [B] = q;
Gm [B] [a] = q;
}
}
/* Input Source and end points */
Scanf ("% d", & s, & e );
/* Perform Dijkstra operations */
Dijkstra (gp, gm, s, n );
/* Output result */
Printf ("% d \ n", node [e]. d, node [e]. m );
/* Release space */
Free (gm );
Free (gp );
/* Wait for data in the next group */
Scanf ("% d", & n, & m );
}
}