A very common idea is to preprocess the two single-source shortest paths of s and T, and then enumerate the commercial lines. The path output can save the PA array at the shortest possible time, or it can be checked with the dist array.
#include <bits/stdc++.h>using namespacestd;Const intMAXN =502, MAXM =2002;intHEAD[MAXN], TO[MAXM], nxt[maxm],wei[maxm],ecnt;voidAddedge (intUintVintW) {to[ecnt]=v; NXT[ECNT]=Head[u]; WEI[ECNT]=W; Head[u]= ecnt++;} typedef pair<int,int>Node;#defineFi first#defineSe SecondConst intINF =0x3f3f3f3f;intD1[MAXN],D2[MAXN];voidDijkstraintSintTint(&d) [MAXN]) {Priority_queue<Node,vector<Node>,greater<Node> >Q; memset (d,0x3f,sizeof(d)); D[s]=0; Q.push (Node (0, s)); while(Q.size ()) {Node x=q.top (); Q.pop (); intU =x.se; if(x.fi! = D[u])Continue; for(inti = Head[u]; ~i; i =Nxt[i]) { intv =To[i]; if(D[v] > d[u]+Wei[i]) {D[v]= d[u]+Wei[i]; Q.push (Node (d[v],v)); } } }}intMain () {//freopen ("In.txt", "R", stdin); intn,s,e; BOOLFirst =true; while(~SCANF ("%d%d%d",&n,&s,&E)) { if(!first) Putchar ('\ n'); First=false; intM scanf"%d",&M); memset (Head,-1,sizeof(head)); ECNT=0; while(m--){ intU,v,w; scanf"%d%d%d",&u,&v,&W); Addedge (--u,--v,w); Addedge (V,U,W); } Dijkstra (--s,--e,d1); Dijkstra (E,S,D2); intPick =-1, p2, ans =D1[e]; intK scanf"%d",&j); for(inti =0; i < K; i++){ intU,v,w; scanf"%d%d%d",&u,&v,&W); if(D1[--u] + W < ans-d2[--v]) {ans= D1[u] + W +D2[v]; Pick= u; P2 =v; }Else if(D2[u] + W < ans-D1[v]) {ans= D2[u] + W +D1[v]; Pick= V; P2 =u; } } intu; if(~pick) {Stack<int>Stk; U=pick; Stk.push (U); while(U! =S) { for(inti = Head[u]; ~i; i =Nxt[i]) { if(D1[u]-wei[i] = =D1[to[i]]) {u= To[i]; Stk.push (U); Break; } } } while(Stk.size ()) {printf ("%d", Stk.top () +1); Stk.pop (); } u=P2; }Else{u=S; } while(U! =E) {printf ("%d", u+1); for(inti = Head[u]; ~i; i =Nxt[i]) { if(D2[u]-wei[i] = =D2[to[i]]) {u= To[i]; Break; }}} printf ("%d\n", e+1); if(~pick) printf ("%d\n", pick+1); ElsePuts"Ticket not used"); printf ("%d\n", ans); } return 0;}
UVA 11374 Airport Express