Http://www.cnblogs.com/wally/archive/2013/04/16/3024490.html
http://blog.csdn.net/me4546/article/details/6584448
Maintenance of shortest short-circuit length d[i][0] and secondary short-circuit d[i][1], shortest-circuit number dp[i][0] and secondary short-circuit dp[i][1]
#include <iostream>#include<string>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<algorithm>#include<stack>#include<queue>#include<cctype>#include<vector>#include<iterator>#include<Set>#include<map>#include<sstream>using namespacestd;#defineMem (A, B) memset (A,b,sizeof (a))#definePF printf#defineSF scanf#defineSPF sprintf#definePB Push_back#defineDebug printf ("!\n")#defineMAXN 5010#defineMAX (A, b) a>b?a:b#defineBlank pf ("\ n")#defineLL Long Long#defineAll (x) X.begin (), X.end ()#defineINS (x) Inserter (X,x.begin ())#definePqueue priority_queue#defineINF 0x3f3f3f3fstructedge{intv,w;}; Vector<Edge> g[ -];structnode{intv,dist; intMark//Mark, 0 is the shortest circuit, 1 is a short circuit; BOOL operator< (ConstNode &p)Const { if(P.dist! =Dist)returnp.dist<Dist; returnp.v<v;//If you don't sort by the size of the vertices here, it's WA. }};intn,m,s,e;intdist[ -][2];intdp[ -][2];BOOLvis[ -][2];//Dp[i][0] Indicates how many bars arrive at the shortest path to point I, dp[i][1] indicates the number of times short//Dist[i][0] Indicates the length of the shortest path to the point I, dist[i][1] indicates the length of the secondary short circuit/*when using V to loosen the u there are four cases (set current Dist[v][cas]) situation 1:dist[v][cas]+w (V,u) <dist[u][0], find a shorter distance, the original shortest distance as the second short distance, At the same time, update the shortest. Dist[u][1]=dist[u][0]dist[u][0]=dist[v][cas]+w (v,u);DP [U][1]=dp[u][0]dp[u][0]=dp[v][cas] and node (dist[u ][0],u,0) and Node (dist[u][1],u,1) into the queue case 2:dist[v][cas]+w (v,u) ==dist[u][0], find a new shortest path of the same distance, then Dp[u][0]+=dp[v][cas], Others do not have to be updated, nor queued to the situation 3:dist[v][cas]+w (V,u) <dist[u][1], not to update the shortest distance, but can be updated twice shorter, then update dist[u][1] and dp[u][1]dist[u][1]=dist[v][ Cas]+w (v,u);DP [U][1]=dp[v][cas]; put node (dist[u][1],u,1) into the queue case 4:dist[v][cas]+w (v,u) ==dist[u][1] Find a new short-circuit of the same distance, the DP [U] [1]+=dp[v][cas], others are not updated. */voidDijkstraintStartintend) { for(intI=0; i<n;i++) {dist[i][0]=dist[i][1]=INF; } memset (DP,0,sizeof(DP)); memset (Vis,false,sizeof(VIS)); Priority_queue<node>Q; Node p,q; dist[start][0]=0; dp[start][0]=1; P.dist=0, p.mark=0, p.v=start; Q.push (P); while(!Q.empty ()) {P=Q.top (); Q.pop (); if(Vis[p.v][p.mark])Continue; //if (dist[p.v][p.mark]!=p.dist) continue;vis[p.v][p.mark]=true; for(intI=0; I<g[p.v].size (); i++) { intv=g[p.v][i].v; intw=G[P.V][I].W; if(!vis[v][0] && p.dist+w <dist[v][0]) { //may be a secondary short circuit if(dist[v][0]!=INF) {Q.V=v,q.dist=dist[v][1],q.mark=1; dist[v][1]=dist[v][0]; dp[v][1]=dp[v][0]; Q.push (q); } dist[v][0]=p.dist+W; dp[v][0]=Dp[p.v][p.mark]; Q.V=v,q.dist=dist[v][0],q.mark=0; Q.push (q); } Else if(!vis[v][0] && p.dist+w==dist[v][0]) {dp[v][0]+=Dp[p.v][p.mark]; } Else if(!vis[v][1] && p.dist+w<dist[v][1]) {dist[v][1]=p.dist+W; dp[v][1]=Dp[p.v][p.mark]; Q.dist=dist[v][1],q.v=v,q.mark=1; Q.push (q); } Else if(!vis[v][1]&&p.dist+w==dist[v][1]) {dp[v][1]+=Dp[p.v][p.mark]; } } }}intMain () { while(~SCANF ("%d%d%d%d",&n,&m,&s,&e)) { for(intI=0; i<n;i++) g[i].clear (); for(intI=1; i<=m;i++) { intu,v,w; scanf ("%d%d%d",&u,&v,&W); Edge p; P.V=v,p.w=W; G[u].push_back (P); } Dijkstra (S,e); printf ("%d%d\n", dist[e][1],dp[e][1]); } return 0;}
HDU 3,191 Short circuit length and number of strips