日期:2023.10.17
第7天
题目来源:算法笔记
代码:
/*
在找寻最短路径的时候,图中可能有多个最短路径,
此时题目会有第二个标尺,按照第二标尺,选出最短路径中最优的那条;
采用一个极其强大的模板
在Dijkstra()中,专心求解每一个点的最短路径,得到pre[]数组;(由于有多个最短路径,
所有每个点的前驱结点,可能存在多个,所以pre[]的元素应该是容器vector;)
在DFS()中,遍历每一个点,所有的最短路径,这个过程,比较第二标尺,并更新
此时需要不断记录最短路径的线路path[],一旦有第二标尺更优的路径 ,就更新path[]
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1010;
int n;//顶点数
int d[MAXN];//最短距离
vector<int> pre[MAXN]; //前驱点,不用初始化的
bool vis[MAXN] = {0};
int G[MAXN][MAXN];
//只用找出最短路径,赋值pre[]数组:这是个模板函数,雷打不动
void Dijkstra(int s) {
//初始化距离数组
memset(d, 0x3f, sizeof(d));
d[s] = 0;
//一共循环n次
for(int i = 0; i < n; i++) {
//找到非集合S的距离起点最近的点
int u = -1, MIN = INF;
for(int j = 0; j < n; j++) {
if(vis[j] == 0 && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
if( u == -1) return ;
vis[u] = 1;
//更新非集合S中的点到起点的距离
for(int v = 0; v < n; v++) {
if(vis[v] == 0 && 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);
}
}
}
}
}
//遍历所有最短路径,找出第二标尺最优的
int main(void) {
return 0;
}
今天主要学习了,更复杂的图,存在多个最短路径时,需要用到第二标尺找到更优的最短路径,将求解最短路径,和最优的最短路径分别用Dijkstra()和DFS()分开写。