Если свитков и точек интереса немного, то можно решать обходом в ширину на расширенном графе.
Вершина в новом графе характеризуется четверкой чисел: (m, x, y, k) - m - маска уже посещенных интересных точек, x, y - координаты клетки, k - сколько свитков осталось. Ребра в графе хранить не надо, а стоит их рассчитывать на лету. Всегда можно пойти в 4 соседние стороны. При этом x, y, пересчитываются, k не меняется. Маска m получает новый бит, если конечная точка - одна из интересных (через битовое or. Если бит уже был установлен, он не меняется). Если k>0 - то можно телепортироваться. Перебирайте все x', y' в пределах 8 клеток от изначальной. Маска m получает новый бит, если конечная точка интересная. k уменьшается на 1.
Вот по этим четверкам с заданными ребрами запускайте обход в ширину из точки (0, x_start, y_start, N). Как только доходите до точки с маской включающей все интересные точки - вы нашли кратчайший путь.
Чтобы восстановить ответ вам надо для каждой четверки хранить, каким методом вы в нее попали (использовали ли свиток из какой-то точки, или просто пришли из соседней). Надо аккуратно пересчитывать предыдущую четверку в пути. Или можно тупо хранить для каждой четверки предыдущую четверку в пути.
Это будет за O(W^2*H^2*N*2^M)
, если W,H - размеры поля, N - количество свиков, M - количество интересных точек.