2016-11-29 8 views
-1

Есть ли способ изменить это, чтобы показать маршрут кратчайшего пути? Например, если бы у меня был список чисел, подобных (3,1), (3,0), (4,3), (2,1), выход для получения от 4 до 1 был бы 4-> 3,3 -> 1Самая короткая модификация маршрута

// Prints shortest paths from src to all other vertices 
void Graph::shortestPath(int src) 
{ 
    // Create a priority queue to store vertices that 
    // are being preprocessed. This is weird syntax in C++. 
    // Refer below link for details of this syntax 
    // http://geeksquiz.com/implement-min-heap-using-stl/ 
    priority_queue< iPair, vector <iPair> , greater<iPair> > pq; 


    // Create a vector for distances and initialize all 
    // distances as infinite (INF) 
    vector<int> dist(V, INF); 

    // Insert source itself in priority queue and initialize 
    // its distance as 0. 
    pq.push(make_pair(0, src)); 
    dist[src] = 0; 

    /* Looping till priority queue becomes empty (or all 
     distances are not finalized) */ 
    while (!pq.empty()) 
    { 
     // The first vertex in pair is the minimum distance 
     // vertex, extract it from priority queue. 
     // vertex label is stored in second of pair (it 
     // has to be done this way to keep the vertices 
     // sorted distance (distance must be first item 
     // in pair) 
     int u = pq.top().second; 
     pq.pop(); 

     // 'i' is used to get all adjacent vertices of a vertex 
     list< pair<int, int> >::iterator i; 
     for (i = adj[u].begin(); i != adj[u].end(); ++i) 
     { 
      // Get vertex label and weight of current adjacent 
      // of u. 
      int v = (*i).first; 
      int weight = (*i).second; 

      // If there is shorted path to v through u. 
      if (dist[v] > dist[u] + weight) 
      { 
       // Updating distance of v 
       dist[v] = dist[u] + weight; 
       pq.push(make_pair(dist[v], v)); 
      } 
     } 
    } 

    // Print shortest distances stored in dist[] 
    printf("Vertex Distance from Source\n"); 
    for (int i = 0; i < V; ++i) 
      printf("%d \t\t %d\n", i, dist[i]); 
    } 

Ввод в массиве, который хранит номер пути, как 4,3,3,1 (с использованием выше примера), кажется, как лучшая идея, но я не знаю, куда вставить массив в этом коде для этого.

ответ

0

Так же, как вы сохраняете расстояния для каждой вершины в векторе dist, сохраните предшествующую вершину, которая обновила ее в векторе с именем predecessor.

vector<int> dist(V, INF); 
vector<int> predecessor(V, 0); 

Затем, когда вы обновляете расстояние, обновить предшественника:

dist[v] = dist[u] + weight; 
predecessor[v] = u; 

Наконец, вы можете проследить за любой вершины кратчайшего пути (назад) на источник:

printf("Vertex Distance from Source  shortest path from source\n"); 
for (int i = 0; i < V; ++i) 
{ 
     printf("%d \t\t %d\t\t", i, dist[i]); 
     int j = i; 
     do 
     { 
      printf("%d,", j); 
      j = predecessor[j]; 
     } while(j != src); 
     printf("\n"); 
} 
0

Звучит как проблема с домашней работой.

Ваша идея сохранить номера пути будет отличной, если бы это была DFS. К сожалению, алгоритм Джикстры, естественно, не отслеживает путь, как это делает DFS; он просто берет следующий ближайший узел и обновляет значения расстояния. Вероятно, это больше похоже на BFS.

Что вы можете сделать, так это то, что вы обновляете расстояния до каждого узла, как-то храните тот узел, из которого вы пришли (возможно, в вашей структуре iPair, если вам разрешено, возможно, в карте/массиве, если у вас есть способ идентификации ваших узлов). Я назову это ссылкой «из» для этого сообщения. Затем каждый раз, когда вы обнаруживаете более короткий путь к узлу, вы также можете обновить его по ссылке.

Как вы находите путь к данному узлу? Просто: просто начинайте с конечного узла и следуйте «от» ссылок обратно к источнику.

Смежные вопросы