Poj_3255
I was thinking about poj_2449.AlgorithmTle, it seems that only a * can be solved.
Due to the short circuit, the K of the K short circuit is 2, which is relatively small. Therefore, you can directly use dij. My idea is to create a maximum heap and a minimum heap with a capacity not less than K at each point in the graph. The minimum heap is used to obtain the short-circuit value that reaches the current node, the maximum heap is used to save the Shortest Path of the first K.
Finally, in order to query the global minimum value each time, place N points on a line segment tree (minimum heap). The rest is the dij process, when the number of access endpoints reaches the K, the break can be reached, which is the value of the K short circuit.
Of course, this is actually troublesome, because K is actually 2, so you can split a point into two points, one to save the current short-circuit value, one to save the short-circuit value.
# Include <stdio. h>
# Include < String . H>
# Define Maxd 5010
# Define Maxm 200010
# Define Maxt 5
# Define INF 0x3f3f3f
Int Di, do, n, m, K, S, T, first [maxd], next [maxm], V [maxm], W [maxm], tree [ 4 * Maxd], E;
Struct Tree
{
Int Min, min_tree [maxt], max_tree [maxt], a [maxt];
Void Init ()
{
Int I;
Min = inf;
For (I = 0 ; I <di; I ++)
{
Min_tree [I + DI] = max_tree [I + DI] = I;
A [I] = inf;
}
For (I = di- 1 ; I> 0 ; I --)
{
Min_tree [I] = min_tree [I <1 ];
Max_tree [I] = max_tree [I < 1 ];
}
}
Void Update_min ( Int I)
{
For (; I ^ 1 ; I >>= 1 )
Min_tree [I> 1 ] = A [min_tree [I] <A [min_tree [I ^ 1 ]? Min_tree [I]: min_tree [I ^ 1 ];
}
Void Update_max ( Int I)
{
For (; I ^ 1 ; I >>= 1 )
Max_tree [I> 1 ] = A [max_tree [I]> A [max_tree [I ^ 1 ]? Max_tree [I]: max_tree [I ^ 1 ];
}
Int Insert ( Int X)
{
Int K = max_tree [ 1 ];
If (X <A [k])
{
A [k] = x, update_max (di + k), update_min (di + k );
If (X <min)
{
Min = X;
Return 1 ;
}
}
Return 0 ;
}
Void Delete ()
{
Int K = min_tree [ 1 ];
A [k] = inf, update_min (di + k );
Min = A [min_tree [ 1 ];
}
} T [ 2 * Maxd];
Void Add ( Int X, Int Y, Int Z)
{
W [e] = z, V [e] = y;
Next [e] = first [X], first [x] = E;
++ E;
}
Void Init ()
{
Int I, J, K, x, y, z;
For (Do = 1 ; Do <= N; DO <= 1 );
Memset (first + 1 ,- 1 , Sizeof (First [ 0 ]) * N );
E = 0 ;
For (I = 0 ; I <m; I ++)
{
Scanf ( " % D " , & X, & Y, & Z );
Add (x, y, z), add (Y, x, z );
}
S = 1 , T = n, k = 2 ;
For (Di = 1 ; Di <K; Di <= 1 );
}
Void Update ( Int I)
{
For (; I ^ 1 ; I >>= 1 )
Tree [I> 1 ] = T [tree [I]. Min <t [tree [I ^ 1 ]. Min? Tree [I]: Tree [I ^ 1 ];
}
Void Solve ()
{
Int I, J, K, CNT, x, y, z;
Memset (tree + 1 , 0 , Sizeof (Tree [ 0 ]) * (DO < 1 ));
For (I = 0 ; I <do; I ++)
{
T [I]. INIT ();
Tree [I + do] = I;
}
For (I = Do- 1 ; I> 0 ; I --)
Tree [I] = tree [I < 1 ];
T [s]. insert ( 0 ), Update (S + do );
CNT = 0 ;
While (T [x = tree [ 1 ]. Min! = Inf)
{
If (X = T)
{
If (++ CNT = K)
Break ;
}
For (I = first [X]; I! =- 1 ; I = next [I])
If (T [V [I]. insert (T [X]. min + W [I])
Update (V [I] + do );
T [X]. Delete (), update (x + do );
}
If (CNT = K)
Printf ( " % D \ n " , T [tree [ 1 ]. Min );
Else
Printf ( " -1 \ n " );
}
Int Main ()
{
While (Scanf ( " % D " , & N, & M) = 2 )
{
Init ();
Solve ();
}
Return 0 ;
}