算法描述:
1、先在Dijkstra算法中记录下所有的最短路径(只考虑距离)
2、之后在这些最短路径中选出一条第二标尺最优的路径。
接下来实现第一步:记录所有最短路径。
实现代码(考试可以直接照搬默写哈哈哈~):
vector<int> pre[MAXV];
void Dijkstra(int s){
fill(d, d+MAXV, INF); // 将数组d全部赋值为INF
//新添加,将pre[i]全部初始化其本身
for(int i = 0; i < n; i++) pre[i] = i;
d[s] = 0;
for(int i = 0; i < n; i++){
int u = -1, MIN = INF;//u使d[u]最小,MIN存放最小的d[u]
for(int j = 0; j < n; j++){//找到未访问的顶点中d[u]最小的
if(vis[j] == false && d[j] < MIN){
u = j;
MIN = d[j];
}
}
//找不到小于INF的d[u],则说明剩下的顶点与s并不连通
if(u == -1) return;
vis[u] = true;
for(int v = 0; v < n; v++){
if(vis[v] == false && G[u][v] != INF){
if(d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];
pre[v].clear();
pre[v].push_back(u);
}else if(d[u] + G[u][v] == d[v]){
pre[v].push_back(u);
}
}
}
}
}
接下来实现第二步:DFS递归函数
实现代码:
int optvalue; //第二标尺最优值
vector<int> pre[MAXV]; //存放结点的前驱节点
vector<int> path[MAXV], temppath[MAXV]; //最优路径、临时路径
void DFS(int v){
//递归边界
if(v == st){ //如果到达叶子结点st,即路径起点
temppath.push_back(v); //将st加入临时路径
int value;
计算临时路径的value;
if(value 优于 optvalue){
optvalue = value;
path = temppath;
}
temppath.pop_back(); //将刚加入的节点删除
return;
}
temppath.push_back(u); //将当前访问的节点加入临时路径
for(int i = 0; i < pre[v].size(); i++){
DFS(pre[v][i]);//v的前驱节点pre[v][i]
}
temppath.pop_back();// 遍历完所有的前驱节点,将当前节点删除
}
这种算是解决Dijkstra算法的典型模版了~
本人发现其实两种方法只要掌握一种即可~
(尽量都会吧,狗狗祟祟.jpg)