题号 | 题目难点(各题的不同) | 注意事项 |
---|---|---|
1003(25) | 1.求源到目的地最短路的个数 | 最短路的个数不是count[j] = count[index] 而是 count[j] += count[index] |
2. 输出最短路中最大的点权和 | 在路径的最短距离相等时,更新权重 符合贪心的最优原则 |
|
1018(30) | 1. 输出符合题目要求的最短路径 | 需要使用DFS求具体路径 |
2. 在有多条最短路径时按题目要求选择 | 不符合贪心的最优原则 | |
1030(30) | 1.输出符合题目要求的最短路径 | |
2. 在有多条最短路径时选择花费最少的路径 | 符合贪心的最优原则,但是需要保存两个二维数组 | |
1072(30) | 1.处理输入,将G1...Gn转化为index | |
2. 使用多次Dijkstra算法, 源到不同结点的最短路并找到最短路的最大值 |
||
1087(30) | 1. 使用map来为城市名字建立index 使用另一个map保存index和城市名的关系 |
|
2. 输出拥有最大点权的最短路径 | ||
3. 若路径不唯一输出,最短路径中平均点权最大的路径 | 不符合贪心的最优原则 | |
1111(30) | 1. 使用两次Dijkstra算法,得到最短路径和耗时最少的路径 | |
2. 输出最短路径和耗时最少路径 |
主要使用的数据结构如下:
记录各个结点间距离的二维数组:vector<vector<int> > edge
记录source和各个结点间的最短距离的数组:vector<int> dist
记录各个结点是否被访问过的数组:vector<bool> visited
记录源到结点的最短路径的父亲结点 : vector<int> path
例如假设从源(0)到目的地的路径(4)为 0->3->2->1->4
则
path[0]=-1, path[1]=2, path[2]=3,path[3]=0, path[4]=1
此处用-1表示源
具体代码实现模版如下:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define inf 0x7fffffff
vector<vector<int> > shortestPath;
void DFS(vector<vector<int> >& path,int index, vector<int> vec){
if(index==-1){
reverse(vec.begin(),vec.end());
shortestPath.push_back(vec);
return;
}
vec.push_back(index);
for(int i = 0;i<path[index].size();i++){
DFS(path,path[index][i],vec);
}
}
int main(){
int N; //图中顶点的个数,顶点从0-N
int M; //图中边的个数
vector<vector<int> > edge(N, vector<int>(N,-1));
for(int i = 0;i<M;i++){
int a,b,weight;
cin>>a>>b>>weight;
// 此处以无向图为例
edge[a][b] = weight;
edge[b][a] = weight;
}
int source;
cin>>source;
vector<int> visited(N,false);
vector<int> dist(N,inf);
// vector<int> path(N, -1);
vector<vector<int> > path(N);
// 初始化source 到自己的距离为0
dist[source] = 0;
path[source].push_back(-1);
//==================开始Dijkstra算法======================
for(int i = 0;i<N;i++){
int index = -1;
int minDist = inf;
// 找到距离最短的没有访问过的结点
for(int j = 0;j<N;j++){
if(!visited[j] && minDist>dist[j]){
index = j;
minDist = dist[j];
}
}
visited[index] = j;
// 更新最新访问过的结点的相邻结点的距离
for(int j = 0;j<N;j++){
if(!visited[j] && edge[index][j]!=-1){
if(dist[j]>dist[index]+edge[index][j]){
dist[j] = dist[index]+edge[index][j];
vector<int> temp(1,index);
path[j] = temp;
}
else if(dist[j]==dist[index]+edge[index][j]){
//根据题目要求填写
//当存在多条路径时
/* path[j].push_back(index);*/
}
}
}
}
// 采用DFS得到所有的最短路径
vector<int> vec;
DFS(path, index,vec);
// 输出所有的最短路径
for(int i = 0;i<shortestPath.size();i++){
for(int j = 0;j<shortestPath[i].size();j++){
cout<<shortestPath[i][j]<<" ";
}
cout<<endl;
}
}
以上为个人学习总结,如有错误欢迎指出!
原文:https://www.cnblogs.com/zxyLeaf/p/PTA_Dijkstra.html