首页 > 代码库 > hdu 1385 最短路径按字典数输出

hdu 1385 最短路径按字典数输出

  1. #include <stdio.h>
  2. #include <iostream>
  3. using namespace std;
  4. #define INF 999999
  5. #define MAX 11000
  6. int dist[MAX], pre[MAX], path[MAX][MAX], sum, tax[MAX];
  7. bool sign[MAX];
  8. void initialize(int n) //初始化
  9. {
  10. //sum = 0;
  11. for(int i=1; i<=n; i++)
  12. {
  13. {
  14. //pre[i] = 0;
  15. dist[i] = INF; //将距离开始全变为最大
  16. //sign[i] = false;
  17. tax[i] = 0;
  18. }
  19. for(int j=1; j<=n; j++)
  20. path[i][j] = INF; //图初始
  21. }
  22. }
  23. /*坑爹的数据啊!Note: if there are more minimal paths, output the lexically smallest one. Print a blank line after each test case.
  24. 需要比较一下然后按字典最小输出。
  25. 4
  26. 0 2 3 9
  27. 2 0 1 5
  28. 3 1 0 3
  29. 9 5 3 1
  30. 0 0 0 0
  31. 1 4
  32. */
  33. int com(int cur,int v,int a,int b)
  34. {
  35. int path1[MAX];
  36. int path2[MAX];
  37. path1[0]=cur;
  38. path2[0]=cur;
  39. int i=2,j=2;
  40. path1[1]=a;
  41. path2[1]=b;
  42. while(a!=v)
  43. {
  44. path1[i++]=pre[a];
  45. a = pre[a];
  46. }
  47. while(b!=v)
  48. {
  49. path2[j++]=pre[b];
  50. b= pre[b];
  51. }
  52. while(1)
  53. {
  54. i--,j--;
  55. if(i<0) return path1[1];
  56. else if(j<0) return path2[1];
  57. if(path1[i]<path2[j])return path1[1];
  58. else if(path1[i]>path2[j])
  59. return path2[1];
  60. }
  61. }
  62. void dijkstra(int n, int source ,int end)
  63. {
  64. for(int i=1; i<=n; i++)
  65. {
  66. dist[i] = path[source][i]; //将与源点有关的点的距离加入dist
  67. sign[i] = false;
  68. if(dist[i] == INF) //确定有关系的点的前驱,无则为0
  69. pre[i] = 0;
  70. else
  71. pre[i] = source;
  72. }
  73. dist[source] = 0; //源点自身长度为0
  74. sign[source] = 1;
  75. /*
  76. 依次将未放入sign集合的结点中,取dist[]最小值的结点,放入结合sign中
  77. 一旦sign包含了所有n中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
  78. */
  79. for(int i=1; i<=n; i++)
  80. {
  81. int min = INF;
  82. int current = source;
  83. for(int j=1; j<=n; j++) //找出当前未使用点j的dist[j]的最小值
  84. {
  85. if( (!sign[j]) && (dist[j])< min )
  86. {current = j; min = dist[j] ;}
  87. //else if( (!sign[j]) && j == end && dist[j] < min )
  88. //{current = j; min = dist[j];}
  89. }
  90. sign[current] = true; //表示当前点最短距离已经找到
  91. for(int j=1; j<=n; j++) //更新当前点到未找到点的距离
  92. {
  93. if(path[current][j] == INF) continue;
  94. int newdist =tax[current] + dist[current] + path[current][j];
  95. if( (!sign[j]) && newdist < dist[j])
  96. {
  97. dist[j] = newdist;
  98. pre[j] = current;
  99. //if(newdist <= dist[j] )
  100. //{dist[j] = newdist; pre[j] = current;}
  101. }
  102. else if(!sign[j]&& newdist == dist[j])
  103. pre[j]= com(j,source,pre[j],current);
  104. }
  105. }
  106. }
  107. void search_path(int n, int start, int end)
  108. {
  109. int road[MAX];
  110. int total = 1;
  111. road[total++] = end; //从后向前查找
  112. int current = pre[end]; //路径存在pre中
  113. while( current != start) //递归查找,类似并查集
  114. {
  115. road[total++] = current;
  116. sum += tax[current];
  117. current = pre[current];
  118. }
  119. road[total] = start; //最后的开始点存入
  120. printf("Path: ");
  121. for(int i=total; i>=1; i--) //输出
  122. {
  123. if( i!=1)
  124. printf("%d-->", road[i]);
  125. else
  126. printf("%d\n", road[i]);
  127. }
  128. }
  129. void input(int line)
  130. {
  131. //int a, b, weight;
  132. for(int i=1; i<=line; i++)
  133. {
  134. for(int j=1; j<=line; j++)
  135. {
  136. int weight;
  137. scanf("%d", &weight);
  138. //if(path[i][j] > weight && i!=j) //有多条路,保存最短的那条
  139. {
  140. if(weight > 0)
  141. path[i][j] = weight;
  142. //path[j][i] = weight; //无向图双向
  143. }
  144. }
  145. }
  146. for(int i=1; i<=line; i++)
  147. scanf("%d", &tax[i]);
  148. }
  149. int main()
  150. {
  151. int n;
  152. while( scanf("%d", &n)!=EOF && n)
  153. {
  154. initialize(n);
  155. input(n);
  156. int a, b;
  157. while( scanf("%d%d", &a, &b)!=EOF && a!=-1)
  158. {
  159. sum = 0;
  160. printf("From %d to %d :\n", a, b);
  161. if(a==b){
  162. cout <<"Path: "<<a<<endl;
  163. cout <<"Total cost : 0"<<endl;
  164. cout <<endl;
  165. }
  166. else{
  167. dijkstra(n, a, b);
  168. search_path(n, a, b);
  169. printf("Total cost : %d\n\n", dist[b]);}
  170. }
  171. }
  172. return 0;
  173. }
  174. /*
  175. Problem Description
  176. These are N cities in Spring country. Between each pair of cities there may be one transportation track or none. Now there is some cargo that should be delivered from one city to another. The transportation fee consists of two parts:
  177. The cost of the transportation on the path between these cities, and
  178. a certain tax which will be charged whenever any cargo passing through one city, except for the source and the destination cities.
  179. You must write a program to find the route which has the minimum cost.
  180. Input
  181. First is N, number of cities. N = 0 indicates the end of input.
  182. The data of path cost, city tax, source and destination cities are given in the input, which is of the form:
  183. a11 a12 ... a1N
  184. a21 a22 ... a2N
  185. ...............
  186. aN1 aN2 ... aNN
  187. b1 b2 ... bN
  188. c d
  189. e f
  190. ...
  191. g h
  192. where aij is the transport cost from city i to city j, aij = -1 indicates there is no direct path between city i and city j. bi represents the tax of passing through city i. And the cargo is to be delivered from city c to city d, city e to city f, ..., and g = h = -1. You must output the sequence of cities passed by and the total cost which is of the form:
  193. Output
  194. From c to d :
  195. Path: c-->c1-->......-->ck-->d
  196. Total cost : ......
  197. ......
  198. From e to f :
  199. Path: e-->e1-->..........-->ek-->f
  200. Total cost : ......
  201. Note: if there are more minimal paths, output the lexically smallest one. Print a blank line after each test case.
  202. Sample Input
  203. 5
  204. 0 3 22 -1 4
  205. 3 0 5 -1 -1
  206. 22 5 0 9 20
  207. -1 -1 9 0 4
  208. 4 -1 20 4 0
  209. 5 17 8 3 1
  210. 1 3
  211. 3 5
  212. 2 4
  213. -1 -1
  214. 0
  215. Sample Output
  216. From 1 to 3 :
  217. Path: 1-->5-->4-->3
  218. Total cost : 21
  219. From 3 to 5 :
  220. Path: 3-->4-->5
  221. Total cost : 16
  222. From 2 to 4 :
  223. Path: 2-->1-->5-->4
  224. Total cost : 17
  225. */



来自为知笔记(Wiz)


附件列表

     

    hdu 1385 最短路径按字典数输出