Topic links: https://ac.nowcoder.com/acm/contest/1168/C
Is the most common short-circuit, built from the point of view of even less than the two-way side m, since that write a lot but do not know how the shortest path shortest of record. Record enough in relaxation, the relaxation is recorded each time point was slack precursor, so that when a point repeatedly relaxation, you can update several times its predecessor, can not slack when it is the point on the shortest path, that is, the last recorded slack precursor.
And from the end traversing precursor, present in the array to output a reverse shortest path through the output point.
code show as below:
1 #include<bits/stdc++.h> 2 #define mem(a,b) memset(a,b,sizeof(a)) 3 const int MAXN = 650; 4 const double inf = 0x3f3f3f3f * 1.0; 5 using namespace std; 6 7 int n, k; 8 double m, dis[MAXN]; 9 int head[MAXN], cnt, vis[MAXN]; 10 int pre[MAXN]; 11 12 struct Node 13 { 14 double x, y, z; 15 }node[MAXN]; 16 17 struct Edge 18 { 19 int to, next; 20 double w; 21 }edge[MAXN * MAXN]; 22 23 struct N 24 { 25 int pot; 26 double dis; 27 bool operator < (const N &a)const 28 { 29 return dis > a.dis; 30 } 31 }no; 32 33 void add(int a, int b, double c) 34 { 35 cnt ++; 36 edge[cnt].to = b; 37 edge[cnt].next = head[a]; 38 edge[cnt].w = c; 39 head[a] = cnt; 40 } 41 42 void dij() 43 { 44 priority_queue<N> Q; 45 no.pot = 0, no.dis = 0; 46 fill(dis, dis + n + 2, inf), mem(vis, 0); 47 dis[0] = 0; 48 Q.push(no); 49 N a; 50 while(!Q.empty()) 51 { 52 a = Q.top(); 53 Q.pop(); 54 if(vis[a.pot]) 55 continue; 56 vis[a.pot] = 1; 57 for(int i = head[a.pot]; i != -1; i = edge[i].next) 58 { 59 60 int to = Edge [I] .to; 61 is IF (DIS [to]> DIS [a.pot] + Edge [I] .W) 62 is { 63 is DIS [to] DIS = [a.pot] + Edge [I] .W; 64 no.pot = to, no.dis = DIS [to]; 65 pre [to] = a.pot; // relaxation record is updated, it updates the last recorded some slack to the minimum point on the path 66 Q.push (NO); 67 } 68 } 69 } 70 } 71 is 72 int main () 73 { 74 mem(head, -1), cnt = 0; 75 scanf("%d%lf", &n, &m); 76 scanf("%lf%lf%lf%lf%lf%lf", &node[0].x, &node[0].y, &node[0].z, &node[n + 1].x, &node[n + 1].y, &node[n + 1].z); //起点 终点 77 for(int i = 1; i <= n; i ++) 78 scanf("%lf%lf%lf", &node[i].x, &node[i].y, &node[i].z); 79 for(int i = 0; i < n + 1; i ++) 80 { 81 for(int j = i + 1; j <= n + 1; j ++) 82 { 83 double jl = (node[i].x - node[j].x) * (node[i].x - node[j].x) + (node[i].y - node[j].y) * (node[i].y - node[j].y) + (node[i].z - node[j].z) * (node[i].z - node[j].z); 84 if(jl <= m * m) 85 { 86 add(i, j, sqrt(jl)); 87 add(j, i, sqrt(jl)); 88 } 89 } 90 } 91 dij(); 92 if(dis[n + 1] != inf * 1.0) 93 { 94 printf("%.3lf\n", dis[n + 1]); 95 printf("Start "); 96 int p, len = 0, ans[MAXN]; 97 p = n + 1; // end 98 the while (P =! 0 ) // when the starting point is not equal to 99 { 100 ANS [len ++] = P; 101 P = pre [P]; 102 } 103 for ( int I = len . 1 ; I> 0 ; i-- ) 104 the printf ( " % D " , ANS [I]); 105 the printf ( " End \ n- " ); 106 } 107 the else 108 printf("-1\n"); 109 return 0; 110 }