ОГЭ по информатике · задание 4

Таблица дорог: кратчайший путь

Дана таблица длин дорог между пунктами. Нужно найти длину кратчайшего пути между двумя пунктами, иногда — с обязательным заездом в третий.

Как читать таблицу

  • На пересечении строки и столбца — длина дороги между пунктами.
  • Пустая клетка — прямой дороги нет.
  • Таблица симметрична: из A в B столько же, сколько из B в A.

Как решать

  1. Нарисовать схему: пункты — точки, дороги — линии с длинами.
  2. Перебрать пути от начала к концу, не заходя в пункт дважды.
  3. Выбрать наименьшую сумму. Прямая дорога не обязательно самая короткая.

Типичные ошибки

  • Взять прямую дорогу и не проверить объезды.
  • Пропустить дорогу при переносе таблицы на схему.
  • В задаче «через пункт» забыть заехать в этот пункт.

Разобранные варианты

Сначала реши сам, потом открой разбор. В разборе — самые короткие пути и программа на Python.

Вариант 1

5 пунктов

Между населёнными пунктами A, B, C, D, E построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDE
A644
B52
C6585
D488
E4258

Определите длину кратчайшего пути между пунктами B и D. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямой дороги B–D нет.

Шаг 2. Перебираем пути из B в D, не заходя в пункт дважды. Всего таких путей 10; самые короткие:

ПутьДлины дорогИтого
B–E–A–D2 + 4 + 410
B–E–D2 + 810
B–C–D5 + 813
B–C–A–D5 + 6 + 415
B–E–C–D2 + 5 + 815
B–E–C–A–D2 + 5 + 6 + 417

Шаг 3. Наименьшая длина — 10 км.

Ответ: 10

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'C': 6, 'D': 4, 'E': 4}, 'B': {'C': 5, 'E': 2}, 'C': {'A': 6, 'B': 5, 'D': 8, 'E': 5}, 'D': {'A': 4, 'C': 8, 'E': 8}, 'E': {'A': 4, 'B': 2, 'C': 5, 'D': 8}}

best = None
def go(v, visited, dist):
    global best
    if v == 'D':
        if best is None or dist < best:
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('B', {'B'}, 0)
print(best)

Вариант 2

5 пунктов

Между населёнными пунктами A, B, C, D, E построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDE
A47
B27
C279
D47
E779

Определите длину кратчайшего пути между пунктами B и A. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямой дороги B–A нет.

Шаг 2. Перебираем пути из B в A, не заходя в пункт дважды. Всего таких путей 4; самые короткие:

ПутьДлины дорогИтого
B–C–D–A2 + 7 + 413
B–E–A7 + 714
B–C–E–A2 + 9 + 718
B–E–C–D–A7 + 9 + 7 + 427

Шаг 3. Наименьшая длина — 13 км.

Ответ: 13

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'D': 4, 'E': 7}, 'B': {'C': 2, 'E': 7}, 'C': {'B': 2, 'D': 7, 'E': 9}, 'D': {'A': 4, 'C': 7}, 'E': {'A': 7, 'B': 7, 'C': 9}}

best = None
def go(v, visited, dist):
    global best
    if v == 'A':
        if best is None or dist < best:
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('B', {'B'}, 0)
print(best)

Вариант 3

5 пунктов

Между населёнными пунктами A, B, C, D, E построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDE
A4118
B481
C18
D114
E84

Определите длину кратчайшего пути между пунктами B и C. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямая дорога B–C длиной 8 км длиннее объезда.

Шаг 2. Перебираем пути из B в C, не заходя в пункт дважды. Всего таких путей 4; самые короткие:

ПутьДлины дорогИтого
B–D–A–C1 + 1 + 13
B–A–C4 + 15
B–C88
B–D–E–A–C1 + 4 + 8 + 114

Шаг 3. Наименьшая длина — 3 км.

Ответ: 3

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'B': 4, 'C': 1, 'D': 1, 'E': 8}, 'B': {'A': 4, 'C': 8, 'D': 1}, 'C': {'A': 1, 'B': 8}, 'D': {'A': 1, 'B': 1, 'E': 4}, 'E': {'A': 8, 'D': 4}}

best = None
def go(v, visited, dist):
    global best
    if v == 'C':
        if best is None or dist < best:
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('B', {'B'}, 0)
print(best)

Вариант 4

5 пунктов

Между населёнными пунктами A, B, C, D, E построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDE
A369
B898
C385
D69
E985

Определите длину кратчайшего пути между пунктами D и E. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямой дороги D–E нет.

Шаг 2. Перебираем пути из D в E, не заходя в пункт дважды. Всего таких путей 6; самые короткие:

ПутьДлины дорогИтого
D–A–C–E6 + 3 + 514
D–A–E6 + 915
D–B–E9 + 817
D–B–C–E9 + 8 + 522
D–A–C–B–E6 + 3 + 8 + 825
D–B–C–A–E9 + 8 + 3 + 929

Шаг 3. Наименьшая длина — 14 км.

Ответ: 14

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'C': 3, 'D': 6, 'E': 9}, 'B': {'C': 8, 'D': 9, 'E': 8}, 'C': {'A': 3, 'B': 8, 'E': 5}, 'D': {'A': 6, 'B': 9}, 'E': {'A': 9, 'B': 8, 'C': 5}}

best = None
def go(v, visited, dist):
    global best
    if v == 'E':
        if best is None or dist < best:
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('D', {'D'}, 0)
print(best)

Вариант 5

6 пунктов

Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDEF
A8262
B1249
C811
D2211
E649
F2919

Определите длину кратчайшего пути между пунктами E и F. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямая дорога E–F длиной 9 км длиннее объезда.

Шаг 2. Перебираем пути из E в F, не заходя в пункт дважды. Всего таких путей 17; самые короткие:

ПутьДлины дорогИтого
E–B–C–D–F4 + 1 + 1 + 17
E–B–D–F4 + 2 + 17
E–A–F6 + 28
E–A–D–F6 + 2 + 19
E–F99
E–B–C–D–A–F4 + 1 + 1 + 2 + 210

Шаг 3. Наименьшая длина — 7 км.

Ответ: 7

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'C': 8, 'D': 2, 'E': 6, 'F': 2}, 'B': {'C': 1, 'D': 2, 'E': 4, 'F': 9}, 'C': {'A': 8, 'B': 1, 'D': 1}, 'D': {'A': 2, 'B': 2, 'C': 1, 'F': 1}, 'E': {'A': 6, 'B': 4, 'F': 9}, 'F': {'A': 2, 'B': 9, 'D': 1, 'E': 9}}

best = None
def go(v, visited, dist):
    global best
    if v == 'F':
        if best is None or dist < best:
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('E', {'E'}, 0)
print(best)

Вариант 6

6 пунктов

Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDEF
A6736
B2
C6282
D783
E3885
F6235

Определите длину кратчайшего пути между пунктами B и E. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямой дороги B–E нет.

Шаг 2. Перебираем пути из B в E, не заходя в пункт дважды. Всего таких путей 11; самые короткие:

ПутьДлины дорогИтого
B–C–F–E2 + 2 + 59
B–C–E2 + 810
B–C–A–E2 + 6 + 311
B–C–F–A–E2 + 2 + 6 + 313
B–C–F–D–E2 + 2 + 3 + 815
B–C–F–D–A–E2 + 2 + 3 + 7 + 317

Шаг 3. Наименьшая длина — 9 км.

Ответ: 9

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'C': 6, 'D': 7, 'E': 3, 'F': 6}, 'B': {'C': 2}, 'C': {'A': 6, 'B': 2, 'E': 8, 'F': 2}, 'D': {'A': 7, 'E': 8, 'F': 3}, 'E': {'A': 3, 'C': 8, 'D': 8, 'F': 5}, 'F': {'A': 6, 'C': 2, 'D': 3, 'E': 5}}

best = None
def go(v, visited, dist):
    global best
    if v == 'E':
        if best is None or dist < best:
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('B', {'B'}, 0)
print(best)

Вариант 7

6 пунктов

Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDEF
A151
B19976
C59
D19
E7
F6

Определите длину кратчайшего пути между пунктами F и D. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямой дороги F–D нет.

Шаг 2. Перебираем пути из F в D, не заходя в пункт дважды. Всего таких путей 3; самые короткие:

ПутьДлины дорогИтого
F–B–A–D6 + 1 + 18
F–B–D6 + 915
F–B–C–A–D6 + 9 + 5 + 121

Шаг 3. Наименьшая длина — 8 км.

Ответ: 8

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'B': 1, 'C': 5, 'D': 1}, 'B': {'A': 1, 'C': 9, 'D': 9, 'E': 7, 'F': 6}, 'C': {'A': 5, 'B': 9}, 'D': {'A': 1, 'B': 9}, 'E': {'B': 7}, 'F': {'B': 6}}

best = None
def go(v, visited, dist):
    global best
    if v == 'D':
        if best is None or dist < best:
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('F', {'F'}, 0)
print(best)

Вариант 8

5 пунктов · через D

Между населёнными пунктами A, B, C, D, E построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDE
A71
B83
C7832
D332
E122

Определите длину кратчайшего пути между пунктами A и B, проходящего через пункт D. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямой дороги A–B нет.

Шаг 2. Перебираем пути из A в B через D, не заходя в пункт дважды. Всего таких путей 5; самые короткие:

ПутьДлины дорогИтого
A–E–D–B1 + 2 + 36
A–E–C–D–B1 + 2 + 3 + 39
A–C–D–B7 + 3 + 313
A–C–E–D–B7 + 2 + 2 + 314
A–E–D–C–B1 + 2 + 3 + 814

Шаг 3. Наименьшая длина — 6 км.

Ответ: 6

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'C': 7, 'E': 1}, 'B': {'C': 8, 'D': 3}, 'C': {'A': 7, 'B': 8, 'D': 3, 'E': 2}, 'D': {'B': 3, 'C': 3, 'E': 2}, 'E': {'A': 1, 'C': 2, 'D': 2}}

best = None
def go(v, visited, dist):
    global best
    if v == 'B':
        if 'D' in visited and (best is None or dist < best):
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('A', {'A'}, 0)
print(best)

Вариант 9

6 пунктов · через F

Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDEF
A453
B467
C5622
D299
E39
F729

Определите длину кратчайшего пути между пунктами E и B, проходящего через пункт F. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямой дороги E–B нет.

Шаг 2. Перебираем пути из E в B через F, не заходя в пункт дважды. Всего таких путей 6; самые короткие:

ПутьДлины дорогИтого
E–A–C–F–B3 + 5 + 2 + 717
E–D–C–F–B9 + 2 + 2 + 720
E–D–F–B9 + 9 + 725
E–A–C–D–F–B3 + 5 + 2 + 9 + 726
E–D–F–C–B9 + 9 + 2 + 626
E–D–F–C–A–B9 + 9 + 2 + 5 + 429

Шаг 3. Наименьшая длина — 17 км.

Ответ: 17

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'B': 4, 'C': 5, 'E': 3}, 'B': {'A': 4, 'C': 6, 'F': 7}, 'C': {'A': 5, 'B': 6, 'D': 2, 'F': 2}, 'D': {'C': 2, 'E': 9, 'F': 9}, 'E': {'A': 3, 'D': 9}, 'F': {'B': 7, 'C': 2, 'D': 9}}

best = None
def go(v, visited, dist):
    global best
    if v == 'B':
        if 'F' in visited and (best is None or dist < best):
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('E', {'E'}, 0)
print(best)

Вариант 10

6 пунктов

Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDEF
A161
B132
C96
D6397
E177
F267

Определите длину кратчайшего пути между пунктами D и E. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Разбор

Шаг 1. Смотрим, куда можно поехать. В строке пункта записаны длины дорог из него; пустая клетка — дороги нет. Прямая дорога D–E длиной 7 км длиннее объезда.

Шаг 2. Перебираем пути из D в E, не заходя в пункт дважды. Всего таких путей 7; самые короткие:

ПутьДлины дорогИтого
D–B–A–E3 + 1 + 15
D–A–E6 + 17
D–E77
D–B–F–E3 + 2 + 712
D–A–B–F–E6 + 1 + 2 + 716
D–C–F–B–A–E9 + 6 + 2 + 1 + 119

Шаг 3. Наименьшая длина — 5 км.

Ответ: 5

Решение на Python. Рекурсивный перебор всех путей без повторов пунктов.

roads = {'A': {'B': 1, 'D': 6, 'E': 1}, 'B': {'A': 1, 'D': 3, 'F': 2}, 'C': {'D': 9, 'F': 6}, 'D': {'A': 6, 'B': 3, 'C': 9, 'E': 7}, 'E': {'A': 1, 'D': 7, 'F': 7}, 'F': {'B': 2, 'C': 6, 'E': 7}}

best = None
def go(v, visited, dist):
    global best
    if v == 'E':
        if best is None or dist < best:
            best = dist
        return
    for u, w in roads[v].items():
        if u not in visited:
            go(u, visited | {u}, dist + w)

go('D', {'D'}, 0)
print(best)

Для самостоятельного решения

Варианты 11–15 без разборов. Ответ можно проверить кнопкой.

Вариант 11

5 пунктов

Между населёнными пунктами A, B, C, D, E построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDE
A9
B172
C919
D799
E29

Определите длину кратчайшего пути между пунктами A и E. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Вариант 12

6 пунктов

Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDEF
A4933
B4619
C9653
D31572
E3937
F2

Определите длину кратчайшего пути между пунктами F и E. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Вариант 13

6 пунктов · через D

Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDEF
A2411
B2719
C47557
D15
E1958
F178

Определите длину кратчайшего пути между пунктами F и B, проходящего через пункт D. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Вариант 14

5 пунктов · через D

Между населёнными пунктами A, B, C, D, E построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDE
A4328
B435
C39
D232
E8592

Определите длину кратчайшего пути между пунктами C и E, проходящего через пункт D. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.

Вариант 15

6 пунктов

Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость которых (в километрах) приведена в таблице.

ABCDEF
A418
B41284
C134
D1231
E841
F84

Определите длину кратчайшего пути между пунктами A и F. Передвигаться можно только по дорогам, протяжённость которых указана в таблице. Каждый пункт можно посетить только один раз.