fork(1) download
  1. <?php
  2.  
  3. /* http://d...content-available-to-author-only...2.net/ */
  4.  
  5. define('SUBWAY', "едешь на метро");
  6. define('FOOT', "идешь пешком");
  7. define('BUS', "едешь на автобусе");
  8.  
  9. define('P_PET', 0);
  10. define('P_CHK', 1);
  11. define('P_GOR', 2);
  12. define('P_SPO', 3);
  13. define('P_VAS', 4);
  14. define('P_KRE', 5);
  15. define('P_LET', 6);
  16. define('P_DVO', 7);
  17. define('P_ISA', 8);
  18. define('P_NOV', 9);
  19. define('P_RAS', 10);
  20. define('P_GOS', 11);
  21. define('P_SEN', 12);
  22. define('P_VLA', 13);
  23. define('P_VIT', 14);
  24. define('P_TEH', 15);
  25.  
  26. define('PATH_TO_ITSELF', -1);
  27.  
  28. /* Чтобы не писать много раз array('time' => ..., 'by' => ...), используем функцию.
  29.   «canGet» переводится как «можно попасть» */
  30. function canGet($time, $byWhat) {
  31. return array('time' => $time, 'by' => $byWhat);
  32. }
  33.  
  34. $pointNames = array(
  35. P_PET => 'ст. м. Петроградская',
  36. P_CHK => 'ст. м. Чкаловская',
  37. P_GOR => 'ст. м. Горьковская',
  38. P_SPO => 'ст. м. Спортивная',
  39. P_VAS => 'ст. м. Василеостровская',
  40. P_KRE => 'Петропавловская крепость',
  41. P_LET => 'Летний сад',
  42. P_DVO => 'Дворцовая площадь',
  43. P_ISA => 'Исакиевский собор',
  44. P_NOV => 'Новая Голландия',
  45. P_RAS => 'Дом Раскольникова',
  46. P_GOS => 'Гостиный Двор',
  47. P_SEN => 'Сенная Площадь',
  48. P_VLA => 'ст. м. Владимирская',
  49. P_VIT => 'Витебский вокзал',
  50. P_TEH => 'Технологический Институт'
  51. );
  52.  
  53. $paths = array(
  54. P_PET => array(
  55. P_CHK => canGet(10, BUS),
  56. P_GOR => canGet(3, SUBWAY)
  57. ),
  58.  
  59. P_CHK => array(
  60. P_PET => canGet(10, BUS),
  61. P_SPO => canGet(3, SUBWAY)
  62. ),
  63.  
  64. P_GOR => array(
  65. P_PET => canGet(3, BUS),
  66. P_KRE => canGet(5, FOOT),
  67. P_GOS => canGet(6, SUBWAY)
  68. ),
  69.  
  70. P_SPO => array(
  71. P_CHK => canGet(3, SUBWAY),
  72. P_VAS => canGet(10, BUS),
  73. P_SEN => canGet(7, SUBWAY)
  74. ),
  75.  
  76. P_VAS => array(
  77. P_SPO => canGet(10, BUS),
  78. P_GOS => canGet(7, SUBWAY),
  79. P_NOV => canGet(11, FOOT)
  80. ),
  81.  
  82. P_KRE => array(
  83. P_GOR => canGet(5, FOOT)
  84. ),
  85.  
  86. P_LET => array(
  87. P_DVO => canGet(6, FOOT),
  88. P_GOS => canGet(7, FOOT)
  89. ),
  90.  
  91. P_DVO => array(
  92. P_ISA => canGet(6, FOOT),
  93. P_GOS => canGet(6, FOOT),
  94. P_LET => canGet(6, FOOT)
  95. ),
  96.  
  97. P_ISA => array(
  98. P_DVO => canGet(6, FOOT),
  99. P_NOV => canGet(5, FOOT)
  100. ),
  101.  
  102. P_NOV => array(
  103. P_VAS => canGet(11, FOOT),
  104. P_ISA => canGet(5, FOOT),
  105. P_RAS => canGet(7, BUS)
  106. ),
  107.  
  108. P_RAS => array(
  109. P_NOV => canGet(7, BUS),
  110. P_SEN => canGet(3, FOOT)
  111. ),
  112.  
  113. P_GOS => array(
  114. P_VAS => canGet(7, SUBWAY),
  115. P_SEN => canGet(3, SUBWAY),
  116. P_DVO => canGet(6, FOOT),
  117. P_GOR => canGet(6, SUBWAY),
  118. P_LET => canGet(7, FOOT),
  119. P_VLA => canGet(7, FOOT)
  120. ),
  121.  
  122. P_SEN => array(
  123. P_RAS => canGet(3, FOOT),
  124. P_SPO => canGet(7, SUBWAY),
  125. P_GOS => canGet(3, SUBWAY),
  126. P_VLA => canGet(4, SUBWAY),
  127. P_VIT => canGet(2, SUBWAY),
  128. P_TEH => canGet(3, SUBWAY)
  129. ),
  130.  
  131. P_VLA => array(
  132. P_SEN => canGet(4, SUBWAY),
  133. P_GOS => canGet(7, FOOT),
  134. P_VIT => canGet(3, SUBWAY)
  135. ),
  136.  
  137. P_VIT => array(
  138. P_SEN => canGet(2, SUBWAY),
  139. P_TEH => canGet(2, SUBWAY),
  140. P_VLA => canGet(3, SUBWAY)
  141. ),
  142.  
  143. P_TEH => array(
  144. P_SEN => canGet(3, SUBWAY),
  145. P_VIT => canGet(2, SUBWAY)
  146. )
  147. );
  148.  
  149.  
  150. /*Функция построения кратчайшего пути.
  151. Возвращает пустой массив, если кратчайший путь не содержит промежуточных нодов.
  152. Иначе, возвращает массив промежуточных нодов.
  153. */
  154. function getPath($start, $end, $interimStep){
  155. $shortestPath = array();
  156. $temp = $end;
  157. for ( ; $temp != $start; $temp = $interimStep[$start][$temp]) {
  158. array_unshift($shortestPath, $temp);
  159. }
  160. return $shortestPath;
  161. }
  162.  
  163. /*
  164. Функция вывода пути.
  165. */
  166. function printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames, $pathCost){
  167. if ($startPoint == $endPoint) {
  168. echo "Ты собираешься попасть в точку, в которой уже находишься.(\"{$pointNames[$startPoint]}\")\n\n";
  169. return;
  170. }
  171. echo "Начальная точка: \"{$pointNames[$startPoint]}\"\n";
  172. $temp = $startPoint;
  173. foreach ($shortestPath as $node) {
  174. echo "Из нее {$paths[$temp][$node]['by']} до точки \"{$pointNames[$node]}\" {$pathCost[$temp][$node]} мин.\n";
  175. $temp = $node;
  176. }
  177. echo "В итоге ты попадешь в точку \"{$pointNames[$endPoint]}\" за {$pathCost[$startPoint][$endPoint]} мин. Приятной поездки!\n\n";
  178. }
  179.  
  180. $numberOfNodes = count($pointNames);
  181.  
  182. /*
  183. Делаем квадратную матрицу путей размера $numberOfNodes, которая будет содержать время кратчайшего пути.
  184. Если путь не существует, то присваиваем ему значение бесконечности.
  185.  
  186. */
  187. $pathCost = array();
  188. for ($i = 0; $i < $numberOfNodes; $i++) {
  189. for ($j = 0; $j < $numberOfNodes; $j++) {
  190. if ($i == $j) {
  191. $pathCost[$i][$j] = 0;
  192. } elseif (!isset($paths[$i][$j]['time'])) {
  193. $pathCost[$i][$j] = INF;
  194. } else {
  195. $pathCost[$i][$j] = $paths[$i][$j]['time'];
  196. }
  197. }
  198. }
  199.  
  200. //Массив, который будет содержать предпоследний шаг кратчайшего пути.
  201. $interimStep = array();
  202. for ($i = 0; $i < $numberOfNodes; $i++) {
  203. $interimStep[$i] = array();
  204. for ($j = 0; $j < $numberOfNodes; $j++) {
  205. if ($i == $j) {
  206. $interimStep[$i][$j] = PATH_TO_ITSELF;
  207. } else {
  208. $interimStep[$i][$j] = $i;
  209. }
  210. }
  211. }
  212.  
  213. //Алгоритм Флойда-Уоршелла.
  214. for ($k = 0; $k < $numberOfNodes; $k++) {
  215. for ($i = 0; $i < $numberOfNodes; $i++) {
  216. for ($j = 0; $j < $numberOfNodes; $j++) {
  217. if (($pathCost[$i][$k] + $pathCost[$k][$j]) < $pathCost[$i][$j]) {
  218. $pathCost[$i][$j] = $pathCost[$i][$k] + $pathCost[$k][$j];
  219. $interimStep[$i][$j] = $interimStep[$k][$j];
  220. }
  221. }
  222. }
  223. }
  224.  
  225. $startPoint = 0; // Петроградская
  226. $endPoint = 9; // Новая Голландия
  227. $shortestPath = getPath($startPoint, $endPoint, $interimStep);
  228. printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames, $pathCost);
  229.  
  230. //Сенная Площадь -> Новая Голландия
  231. $startPoint = 12;
  232. $endPoint = 9;
  233. $shortestPath = getPath($startPoint, $endPoint, $interimStep);
  234. printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames, $pathCost);
  235.  
  236. $startPoint = P_VIT;
  237. $endPoint = P_NOV;
  238. $shortestPath = getPath($startPoint, $endPoint, $interimStep);
  239. printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames, $pathCost);
  240.  
  241. $startPoint = P_LET;
  242. $endPoint = P_KRE;
  243. $shortestPath = getPath($startPoint, $endPoint, $interimStep);
  244. printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames, $pathCost);
  245.  
  246. $startPoint = P_NOV;
  247. $endPoint = P_NOV;
  248. $shortestPath = getPath($startPoint, $endPoint, $interimStep);
  249. printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames, $pathCost);
  250.  
  251. $startPoint = P_VAS;
  252. $endPoint = P_NOV;
  253. $shortestPath = getPath($startPoint, $endPoint, $interimStep);
  254. printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames, $pathCost);
Success #stdin #stdout 0.01s 20520KB
stdin
Standard input is empty
stdout
Начальная точка: "ст. м. Петроградская"
Из нее едешь на метро до точки "ст. м. Горьковская" 3 мин.
Из нее едешь на метро до точки "Гостиный Двор" 6 мин.
Из нее едешь на метро до точки "Сенная Площадь" 3 мин.
Из нее идешь пешком до точки "Дом Раскольникова" 3 мин.
Из нее едешь на автобусе до точки "Новая Голландия" 7 мин.
В итоге ты попадешь в точку "Новая Голландия" за 22 мин. Приятной поездки!

Начальная точка: "Сенная Площадь"
Из нее идешь пешком до точки "Дом Раскольникова" 3 мин.
Из нее едешь на автобусе до точки "Новая Голландия" 7 мин.
В итоге ты попадешь в точку "Новая Голландия" за 10 мин. Приятной поездки!

Начальная точка: "Витебский вокзал"
Из нее едешь на метро до точки "Сенная Площадь" 2 мин.
Из нее идешь пешком до точки "Дом Раскольникова" 3 мин.
Из нее едешь на автобусе до точки "Новая Голландия" 7 мин.
В итоге ты попадешь в точку "Новая Голландия" за 12 мин. Приятной поездки!

Начальная точка: "Летний сад"
Из нее идешь пешком до точки "Гостиный Двор" 7 мин.
Из нее едешь на метро до точки "ст. м. Горьковская" 6 мин.
Из нее идешь пешком до точки "Петропавловская крепость" 5 мин.
В итоге ты попадешь в точку "Петропавловская крепость" за 18 мин. Приятной поездки!

Ты собираешься попасть в точку, в которой уже находишься.("Новая Голландия")

Начальная точка: "ст. м. Василеостровская"
Из нее идешь пешком до точки "Новая Голландия" 11 мин.
В итоге ты попадешь в точку "Новая Голландия" за 11 мин. Приятной поездки!