[英]How can I print the shortest path between two vertices in a graph?
我有一個 Djikstra 算法的工作實現,它計算任意兩個節點之間的最短路徑的長度。 但是如果我需要找到實際路徑,我該如何打印呢? 謝謝!
void djikstra( graph * mygraph )
{
int dist[100] = {INT_MAX};
int i;
//int parent[mygraph->vertices] = {-99};
for ( i = 0; i < 100; i++ )
dist[i] = INT_MAX;
bool arr[100];
for ( i = 0; i < 100; i++ )
arr[i] = false;
int foo;
cout<<"Enter the source vertex\n";
cin>>foo;
dist[foo] = 0;
vector<int> bar;
while (bar.size() != mygraph->vertices)
{
int node = findmin(dist,mygraph->vertices,arr);
arr[node] = true; // so that again and again same node having minimum distance is not returned
bar.push_back(node);
auto it = mygraph->edges[node].begin();
while (it != mygraph->edges[node].end())
{
relax(node,it->first,it->second,dist); // here, it->first represents the node and it->second represents the weight
it++;
}
}
cout<<"Vertex\t"<<"Distance from source\n";
for ( i = 0; i < mygraph->vertices; i++ )
{
cout<<i<<"\t"<<dist[i]<<"\n";
}
cout<<"\n";
return;
}
void relax ( int node, int a, int w, int dist[] )
{
if (dist[a] > dist[node] + w)
{
dist[a] = dist[node] + w;
}
}
您還需要保留從節點映射到其“父節點”的映射。
在這張地圖中,鍵是一個節點,值是用來到達這張地圖的節點。
顯然,源將成為這張地圖的根。
這是通過添加:
parentMap[a] = node;
在松弛步驟中:
void relax ( int node, int a, int w, int dist[] )
{
if (dist[a] > dist[node] + w)
{
dist[a] = dist[node] + w;
parentMap[a] = node;
}
}
一旦你有了這張地圖,獲取路徑就非常容易了,通過以下方式完成:
int current = target;
while (current != source) {
cout << current << ' ';
current = parentMap[current];
}
cout << current << ' ';
請注意,上面以相反的順序打印路徑。 您可以使用列表(並將元素添加到其前面而不是打印元素)以正確順序獲取路徑。
您可以通過父節點追溯您的路徑。
#include<bits/stdc++.h>
using namespace std;
class solution{
public:
void printPath(vector<int> parent, int source, int dest)
{
stack<int> st;
int final = dest;
while(parent[dest] != source)
{
dest = parent[dest];
st.push(dest);
}
cout<<source<<"->";
while(!st.empty())
{
cout<<st.top()<<"->";
st.pop();
}
cout<<final<<endl;
}
void shortestPath(int V, vector<pair<int, int>> G[], int source, int dest)
{
vector<int> dist(V, INT_MAX);
dist[source] = 0;
queue<int> q;
q.push(source);
vector<int> parent(V, -1);
parent[source] = source;
while(!q.empty())
{
int u = q.front();
q.pop();
for(auto node: G[u])
{
int v = node.first;
int wt = node.second;
if(dist[v] > dist[u]+wt)
{
dist[v] = dist[u]+wt;
q.push(v);
parent[v] = u;
}
}
}
cout<<"Cost to reach destination: "<<dist[dest]<<"\n";
printPath(parent, source, dest);
}
};
int main(){
int V, E, source, dest;
cout<<"Enter # of Vertex : ";
cin>>V;
cout<<"Enter # of Edges : ";
cin>>E;
int u, v, wt;
cout<<"Add Edges ->\n";
vector<pair<int, int>> adj[V];
while(E--)
{
cin>>u>>v>>wt;
adj[u].push_back(make_pair(v, wt));
}
cout<<"Enter Source : ";
cin>>source;
cout<<"Enter Destination :";
cin>>dest;
solution* obj = new solution;
obj->shortestPath(V, adj, source, dest);
return 0;
}
上述代碼的輸出如下所示,
Enter # of Vertex : 6
Enter # of Edges : 8
Add Edges ->
0 1 2
1 2 5
2 3 5
3 4 5
4 1 50
4 5 600
1 5 1000
2 4 1
Enter Source : 0
Enter Destination :5
Cost to reach destination: 608
0->1->2->4->5
Shortest Path-Printing using Dijkstra's Algorithm for Graph(這里是為無向圖實現的。以下代碼打印從 source_node 到圖中所有其他節點的最短距離。
它還打印從源節點到用戶請求的節點的最短路徑。 假設,您需要在圖中找到從A到B的最短路徑。 然后輸入A作為源節點, B作為目的節點。
代碼
#include<bits/stdc++.h>
using namespace std;
#define INF (unsigned)!((int)0)
const int MAX=2e4;
vector<pair<int,int>> graph[MAX];
bool visit[MAX];
int dist[MAX];
multiset<pair<int,int>> s;
int parent[MAX]; // used to print the path
int main(){
memset(visit,false,sizeof(visit));
memset(dist,INF,sizeof(dist));
memset(parent,-1,sizeof(parent));
int nodes,edges; cin>>nodes>>edges;
for(auto i=0;i<edges;++i){
int a,b,w;
cin>>a>>b>>w;
graph[a].push_back(make_pair(b,w));
graph[b].push_back(make_pair(a,w)); //Comment it to make the Directed Graph
}
int source_node; cin>>source_node;
dist[source_node]=0;
s.insert(make_pair(0,source_node));
while(!s.empty()){
pair<int,int> elem=*s.begin();
s.erase(s.begin());
int node=elem.second;
if(visit[node])continue;
visit[node]=true;
for(auto i=0;i<graph[node].size();++i){
int dest=graph[node][i].first;
int w=graph[node][i].second;
if(dist[node]+w<dist[dest]){
dist[dest]=dist[node]+w;
parent[dest]=node;
s.insert(make_pair(dist[dest],dest));
}
}
}
cout<<"NODE"<<" "<<"DISTANCE"<<endl;
for(auto i=1;i<=nodes;++i){
cout<<i<<" "<<dist[i]<<endl;
}
/*----PRINT SHORTEST PATH FROM THE SOURCE NODE TO THE NODE REQUESTED-------*/
int node_for_path; cin>>node_for_path;
int dest_node=node_for_path;
stack<int> path;
while(parent[node_for_path]!=source_node){
path.push(node_for_path);
node_for_path=parent[node_for_path];
}
path.push(node_for_path);
path.push(source_node);
cout<<"Shortest Path from "<<source_node<<"to "<<dest_node<<":"<<endl;
while(!path.empty()){
if(path.size()==1) cout<<path.top();
else cout<<path.top()<<"->";
path.pop();
}
return 0;
}
/*TEST CASE*/
9 14 //---NODES,EDGES---
1 2 4 //---START,END,WEIGHT---FOR THE NO OF EDGES
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 1 8
2 8 11
8 9 7
9 7 6
9 3 2
6 3 4
4 6 14
1 //---SOURCE_NODE
5 //-----NODE TO WHICH PATH IS REQUIRED
---END---*/
希望能幫助到你
基於上面的@Dipesh Kurasau,我在下面做了一些代碼:輸出為:總距離=400。 路徑:0 5. 如果注釋掉 v0.adjacents.emplace(&v5, 400); 您會得到與@Dipesh Kurasau 相同的結果。
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
class Vertex
{
public:
Vertex(int i) : id(i) {}
int id;
int toSrcVertex = INT_MAX; // initial distance from this vertex to the source vertex
Vertex* prev = NULL; // point to the previous vertex leading to the source vertex making the shortest path
unordered_map<Vertex*, int> adjacents; //adjacent vertex and its distance;
};
void printPath(Vertex* destination)
{
cout << "total distance =" << destination->toSrcVertex << endl;
cout << "Path:" << endl;
stack<Vertex*> reversed;
while (destination)
{
reversed.push(destination);
destination = destination->prev;
}
while (!reversed.empty())
{
Vertex* t = reversed.top();
reversed.pop();
cout << t->id << " ";
}
cout << "\ndone" << std::flush << endl;
}
void shortest(Vertex* src, Vertex* dest)
{
src->toSrcVertex = 0;
unordered_set<Vertex*> q;
q.insert(src);
unordered_set<Vertex*> visited;
while (!q.empty())
{
Vertex* u = *(q.begin());
q.erase(q.begin());
if (q.empty() && u == dest)
{
// target reached, no more search
return;
}
// vistit all adjacents of Vertex u
for(auto& adj : u->adjacents)
{
Vertex* adjVertex = adj.first;
if (visited.find(adjVertex) != visited.end()) continue;
int distance = adj.second;
int distanceFromUtoAdjVertex = distance + u->toSrcVertex;
if (distanceFromUtoAdjVertex < adjVertex->toSrcVertex)
{
adjVertex->toSrcVertex = distanceFromUtoAdjVertex;
adjVertex->prev = u;
q.insert(adjVertex);
}
}
visited.insert(u);
}
printPath(dest);
}
int main()
{
// construct vertices
Vertex v0(0);
Vertex v1(1);
Vertex v2(2);
Vertex v3(3);
Vertex v4(4);
Vertex v5(5);
// build adjacents (neighboured vertex and distance)
v0.adjacents.emplace(&v1, 2);
v0.adjacents.emplace(&v5, 400);
v1.adjacents.emplace(&v0, 2);
v1.adjacents.emplace(&v2, 5);
v1.adjacents.emplace(&v4, 50);
v1.adjacents.emplace(&v5, 1000);
v2.adjacents.emplace(&v1, 5);
v2.adjacents.emplace(&v3, 5);
v2.adjacents.emplace(&v4, 1);
v3.adjacents.emplace(&v2, 5);
v3.adjacents.emplace(&v4, 5);
v4.adjacents.emplace(&v2, 1);
v4.adjacents.emplace(&v3, 5);
v4.adjacents.emplace(&v1, 50);
v4.adjacents.emplace(&v5, 600);
v5.adjacents.emplace(&v1, 1000);
v5.adjacents.emplace(&v4, 600);
shortest(&v0, &v5);
std::cout << "Hello World!\n" << flush << endl;;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.