dijkstra算法
思想:
用于解决单源最短路问题,即给定有向图G和起点from,通过算法得到from到其他每个顶点的最短距离。
步骤:
- 设置集合selectedNode存放已被访问过的点,每次从未被访问的的结点集合distancemap中找到一个距离起点from最近的点minnode。
- 令minnode为中介点,优化起点与其他所有能从u到达的所有点的最短距离。
- 将minnode加入到已访问结点selectednode中。这样执行n次(图中结点数)以后,直到集合selectednode已包含所有顶点。
map<Node*,int> dijkstra(Node* from){
//从from出发到达所有点的最小距离
//key:从from出发到达key结点
//value:从from出发到达key的最小距离
//若在map中没有某个点的记录,说明从from出发无法到达该点
map<Node*,int>distanceMap;
//起点已经确定,加入到map中
distanceMap[from]=0;
//将求出最短距离的结点存放进去,以后不做修改
set<Node*>selectedNodes;
//从map中找一个距离最小的点,但是不能是已经在selected中锁定的
Node* minNode=getMinDistanceAndUnselectedNode(distanceMap,selectedNodes);
while(minNode!=nullptr){
//获取当前点到起点的距离,以后的所有距离都是在这个基础上增加权值进行比较
int distance=distanceMap[minNode];
//将最小点的边的另一侧的点都找到,进行比较,找到最小值
for(Edge* edge:minNode->edges){
Node* toNode=edge->to;
if(distanceMap.find(toNode)==distanceMap.end()){
//找不到记录说明之前无穷大,直接更新现在的距离
distanceMap[toNode]=distance+edge->weight;
}else{
//若有记录,则与之前的比较,取最小值
distanceMap[edge->to]=min(distanceMap[toNode],distance+edge->weight);
}
}
//将计算后的结果锁定
selectedNodes.insert(minNode);
//更新minNode开始下一次循环
minNode=getMinDistanceAndUnselectedNode(distanceMap,selectedNodes);
}
return distanceMap;
}
Node* getMinDistanceAndUnselectedNode(map<Node*,int>distanceMap,set<Node*> selectedNodes){
Node* minNode=nullptr;
int minDistance=INT_MAX;
for(auto it:distanceMap){
Node* node=it->first;
int diatance=it->second;
//该点不在set中,且距离起点最短
if(selectedNode.find(node)==selectedNode.end()&&distance<minDistance){
minNode=node;
minDistance=distance;
}
}
return minNode;
}