Poj_3635
You can split a point in the graph into a point C + 1 and then apply dij directly. At the same time, the overall status is certain. In order to reduce the decision volume of each step, we can add only one unit each time we refuel.
It seems that dij is faster than spfa, because there are many States, and dij can exit after searching for the destination, which reduces the search volume for a lot of useless states than spfa.
# Include <stdio. h>
# Include < String . H>
# Define Maxd 1010
# Define Maxm 20010
# Define # Maxc 110
# Define Maxt 110000
# Define INF 0x3f3f3f
Int N, m, Q, D, S, E, C, E, cost [maxd], first [maxd], next [maxm], V [maxm], W [maxm];
Int F [maxt], tree [ 4 * Maxt];
Void Update ( Int I)
{
For (; I ^ 1 ; I >>= 1 )
Tree [I> 1 ] = F [tree [I] <F [tree [I ^ 1 ]? Tree [I]: Tree [I ^ 1 ];
}
Void New_edge ( Int X, Int Y, Int Z)
{
V [e] = Y, W [e] = z;
Next [e] = first [X], first [x] = E;
++ E;
}
Void Init ()
{
Int I, J, K, x, y, z;
For (I = 0 ; I <n; I ++)
Scanf ( " % D " , & Cost [I]);
Memset (first ,- 1 , Sizeof (First [ 0 ]) * N );
E = 0 ;
For (I = 0 ; I <m; I ++)
{
Scanf ( " % D " , & X, & Y, & Z );
New_edge (x, y, z), new_edge (Y, x, z );
}
}
Int Get_id ( Int X, Int C)
{
Return X * (C + 1 ) + C + 1 ;
}
Void Divide_id ( Int ID, Int & X, Int & C)
{
C = (ID- 1 ) % (C + 1 );
X = (ID- 1 )/(C + 1 );
}
Void Solve ()
{
Int I, J, K, X, C, ID;
Scanf ( " % D " , & Q );
For (K = 0 ; K <q; k ++)
{
Scanf ( " % D " , & C, & S, & E );
For (D = 1 ; D <n * (C +1 ); D <= 1 );
Memset (F + 1 , 0x3f , Sizeof (F [ 0 ]) * (N * (C + 1 )));
F [ 0 ] = Inf;
Memset (tree + 1 , 0 , Sizeof (Tree [0 ]) * (D < 1 ));
J = get_id (S, 0 );
F [J] = 0 , Tree [J + D] = J, update (J + D );
While (ID = tree [ 1 ])
{
Divide_id (ID, X, C );
If (X = E)
Break ;
Tree [d + id] = 0 , Update (D + id );
If (C <C)
{
J = get_id (x, C + 1 );
If (F [ID] + cost [x] <F [J])
{
F [J] = f [ID] + cost [x];
Tree [J + D] = J, update (J + D );
}
}
For (I = first [X]; I! =- 1 ; I = next [I])
If (C> = W [I])
{
J = get_id (V [I], C-W [I]);
If (F [ID] <F [J])
{
F [J] = f [ID];
Tree [J + D] = J, update (J + D );
}
}
}
If (Tree [ 1 ] = 0 )
Printf ( " Impossible \ n " );
Else
Printf ( " % D \ n " , F [tree [ 1 ]);
}
}
Int Main ()
{
While (Scanf ( " % D " , & N, & M) = 2 )
{
Init ();
Solve ();
}
Return 0 ;
}