Today to achieve a shortest road problem, the original problem https://loj.ac/problem/10081
The main idea is to give a graph with n vertices, points and points between the M1 road, M2 route, the road is bidirectional, and the weight is non-negative, and the route is unidirectional, the weight may be negative, to ensure that there is no road between two points if there is a route. Now given the starting point S, ask S to the shortest path for each point, and if not, output "no path".
I saw this problem that called a happy ah, thought is a water problem, because there is negative right side, can not use Dijkstra, decisive with SPFA, then there is no negative ring it? After the measured data and no negative ring, I thought it would be easy to AC, but the results of the evaluation are as follows:
The last two test points T. Handwriting queue, read-in optimization, various constant optimizations are exhausted, or time-out. Now can basically determine the data of the people of the base card SPFA ...
How to do it, and can not use Dijkstra, then I found a so-and-so seniors (smell angle big fairy).
In the help of so-and-so seniors, I learned about SPFA SLF optimization. Simply say is to use a double-ended queue to achieve SPFA, when a node to be queued, judge it and the size of the team head, if DIS[V]<DIS[H] (V for a queue node, T for Team Head), it is inserted from the team head, or from the end of the team. A bit greedy thought, if this point is smaller than the team head, first use it to relax the other nodes. Some of the code is as follows:
1InlinevoidSPFA (ints)2 { 3Registerintp,h,v,w;4Fill (dis+1, dis+n+1, INF); 5dis[s]=0; 6vis[s]=true; 7Q.push_back (s);8 Do 9 {TenH=Q.front (); Q.pop_front (); Onevis[h]=false; A for(P=tail[h];p; p=e[p].last) - { -v=e[p].v;w=E[P].W; the if(dis[v]>dis[h]+W) - { -dis[v]=dis[h]+W; - if(!Vis[v]) + { - if(Dis[v]<dis[q.front ()])//This is a very important judgment, if the V-point is better than the team head, we'll get it out of the team . +Q.push_front (v); A ElseQ.push_back (v); atvis[v]=true; - } - } - } -} while(!q.empty ()); -}
Post-submission test situation:
Several times faster!
Here I used the handwritten double-ended queue, because faster than using STL, attached to the handwriting code, this should be I have seen the best handwritten double-ended queue way:
structdeque{LL L, R, Q[n]; Deque () {L=0; R =0;} BOOLEmpty () {return! (l ^r);} voidPush_back (LL v) {q[r++] = V; R%=N;} voidPush_front (LL v) {q[l = (L-1+ N)% n] =v;} voidPop_front () {++l; L%=N;} voidPop_back () {R = (R-1+ N)%N;} LL Front () {returnq[l];};
In addition SPFA also has LLL optimization, here will not repeat (in fact, I will not), interested friends can go to understand.
2018-08-17
The SLF optimization--loj#10081 of the SPFA algorithm. "One pass 3.2 practice 7" roads and routes