Test instructions: Tell you about the N points and the one-way edge of M-bar. Ask you about the shortest path from the s point to the e point and the number of roads that are older than the shortest length.
Idea: Dijkstra deformation. From the starting point and the end point to seek one side Dijkstra. The number of paths from the starting point to the first point and the shortest length is recorded with the CNT array, and the shortest length path from the origin point to the first point is reached. The number of paths that the _cnt array records to the first node is the shortest distance of +1. Note that the path recorded by _cnt[i] only includes the first node of the I nodes is the shortest, and the pre node to the first node is not the shortest. This prevents duplicate calculations.
Specific relaxation operation: set U to the point closest to the origin point in the non-past node, then enumerate each edge of u, if DIST[FLAG][U]+E.W==DIST[FLAG][E.V]
The number of paths that reach the V point and are the shortest path cnt[v]+=cnt[u]. If dist[u]+e.w==dist[e.v]+1, then the number of paths to the V-point and Shortest path +1 is _cnt[v]+=cnt[u]. If DIST[U]+E.W<DIST[E.V], first judge dist[flag][u]+e.w such as not equal to dist[e.v]+1, if equal, then the original shortest path number becomes the shortest path length plus 1 of the number of paths _cnt[v]=cnt[v] , if not equal, then the shortest path length plus 1 of the number of paths is 0. Then update dist[v] and let Cnt[v]=cnt[u]. Then in the Dijkstra to find the shortest path from the end to the first point of the number of good, this time Dijkstra do not need to find the shortest path +1 of the number.
Then the final answer is equal to cnt[e] plus the shortest path number from the starting point to the I-point length of the shortest short-circuit length of +1 times the first point to the first I.
#include <cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<string>#include<map>#include<queue>#include<vector>using namespaceStd;typedefLong Longll;Const intinf=0x3f3f3f3f;Const intmaxm=11000;Const intmaxn=1100;structedge{intV,w,nex;} edge[2][MAXM];inthead[2][MAXN];BOOLVIS[MAXN];intdist[2][MAXN];inttot1,tot2,n,m,s,e,u,v,w;intcnt[2][MAXN];int_CNT[MAXN];voidAddedge (intUintVintW) {edge[0][tot1].v=v; edge[0][tot1].w=W; edge[0][tot1].nex=head[0][u]; head[0][u]=tot1++; edge[1][tot2].v=u; edge[1][tot2].w=W; edge[1][tot2].nex=head[1][v]; head[1][v]=tot2++;}voidDijkstraintflag) { intSs=flag?e:s; memset (Vis,0,sizeof(VIS)); for(intI=1; i<=n;i++) Dist[flag][i]=INF; CNT[FLAG][SS]=1; DIST[FLAG][SS]=0; while(1) { intu=-1; for(intv=1; v<=n;v++) if(!vis[v]&& (u==-1|| dist[flag][v]<Dist[flag][u])) U=v; if(u==-1) Break; Vis[u]=true; for(inti=head[flag][u];i!=-1; i=Edge[flag][i].nex) {Edge e=Edge[flag][i]; if(dist[flag][u]+e.w==DIST[FLAG][E.V]) CNT[FLAG][E.V]+=Cnt[flag][u]; if(dist[flag][u]+e.w==dist[flag][e.v]+1&&!flag) _CNT[E.V]+=Cnt[flag][u]; if(dist[flag][u]+e.w<DIST[FLAG][E.V]) { if(!flag) { if(dist[flag][u]+e.w+1==DIST[FLAG][E.V]) _CNT[E.V]=CNT[FLAG][E.V]; Else_CNT[E.V]=0; } DIST[FLAG][E.V]=dist[flag][u]+E.W; CNT[FLAG][E.V]=Cnt[flag][u]; } } }}voidinit () {tot1=tot2=0; memset (Head,-1,sizeof(head)); memset (CNT,0,sizeof(CNT)); memset (_cnt,0,sizeof(CNT));}intMain () {//freopen ("In.txt", "R", stdin); intT; scanf ("%d",&T); while(t--) {init (); scanf ("%d%d",&n,&m); while(m--) {scanf ("%d%d%d",&u,&v,&W); Addedge (U,V,W); } scanf ("%d%d",&s,&e); Dijkstra (0); Dijkstra (1); intans=cnt[0][e]; //printf ("%d\n", ans); //for (int i=1;i<=n;i++)//printf ("%d%d\n", _cnt[i],cnt[1][i]); for(intI=1; i<=n;i++) if(dist[0][i]+dist[1][i]==dist[0][e]) ans+=_cnt[i]*cnt[1][i]; printf ("%d\n", ans); } return 0;}
View Code
POJ 3463-sightseeing