我有一个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;
}
}
答案 0 :(得分:3)
您还需要保留一个从节点映射到其“父”的地图。
在此地图中,键是一个节点,值是用于到达此地图的节点。
显然,来源将成为这张地图的根源。
这是通过添加:
来完成的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 << ' ';
注意,上面以相反的顺序打印路径。您可以使用列表(并在其前面添加元素而不是打印元素)以正确的顺序获取路径。
答案 1 :(得分:0)
使用Dijkstra的图算法最短的路径打印(此处是针对无向图实现的。以下代码显示从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---*/
希望有帮助