【迪杰斯特拉算法】
每轮先更新距离,再选择最近的,用selected数组锁定
没用邻接表也没用邻接矩阵,直接用边集硬干,复杂度有点高
#include<iostream>
#include<vector>
#include<climits>
#include<queue>
using namespace std;
struct Edge{
int a,b,distance,cost;
};
int main(){
int n,m;
int source,destination;
int distance[1001];
int cost[1001];
bool selected[1001];
while(cin>>n>>m){
if(n==0 && m==0) break;
//初始化边集和点集
vector<Edge> edges;
for(int i=0;i<m;i++){
Edge e;
cin>>e.a>>e.b>>e.distance>>e.cost;
edges.push_back(e);
}
for(int i=0;i<=n;i++){
distance[i] = INT_MAX;
cost[i] = INT_MAX;
selected[i] = false;
}
//初始化起点
cin>>source>>destination;
distance[source] = 0;
cost[source] = 0;
selected[source] = true;
//搜索
int current = source;
while(1){
//本轮更新距离
vector<Edge>::iterator it = edges.begin();
while(it!=edges.end()){
if(it->a==current && selected[it->b]==false){
int newDistance = distance[it->a] + it->distance;
int newCost = cost[it->a] + it->cost;
if(newDistance<distance[it->b]){//新路径更近,更新
distance[it->b] = newDistance;
cost[it->b] = newCost;
} else if(newDistance==distance[it->b] && newCost<cost[it->b]){//新路径距离相同,但代价更小
cost[it->b] = newCost;
}
} else if(it->b==current && selected[it->a]==false){
int newDistance = distance[it->b] + it->distance;
int newCost = cost[it->b] + it->cost;
if(newDistance<distance[it->a]){//新路径更近,更新
distance[it->a] = newDistance;
cost[it->a] = newCost;
} else if(newDistance==distance[it->a] && newCost<cost[it->a]){//新路径距离相同,但代价更小
cost[it->a] = newCost;
}
} else {//不可达
}
it++;
}
//本轮选定最近
int minDistance = INT_MAX;
int nearestNode = -1;
for(int i=1;i<=n;i++){
if(selected[i]) continue;
if(distance[i]<minDistance){
minDistance = distance[i];
nearestNode = i;
} else if(distance[i]==minDistance && cost[i]<cost[nearestNode]){
nearestNode = i;
}
}
if(nearestNode==destination || nearestNode==-1) break;
selected[nearestNode] = true;
current = nearestNode;
}
cout<<distance[destination]<<" "<<cost[destination]<<endl;
}
return 0;
}

京公网安备 11010502036488号