有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N?1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
3 40
Dijkstra算法 参考这篇文章,讲的很通俗 https://wiki.jikexueyuan.com/project/easy-learn-algorithm/dijkstra.html
//Dijkstra算法核心语句 //inf为最大值 题目给的是不大于500 这里随便给一个大于500的值就可以 //还需要一个辅助的数组visited[n]用于标记是否遍历过结点 for(i=0;i<n;i++) { //找到离1号顶点最近的顶点 min=inf; for(j=0;j<n;j++) { if(visited[j]==0 && dis[j]<min) { min=dis[j]; u=j; } } visited[u]=1; for(v=0;v<n;v++) { if(e[u][v]<inf) { if(dis[v]>dis[u]+e[u][v]) dis[v]=dis[u]+e[u][v]; } } }
#include <iostream> #include <vector> using namespace std; class vertexNode{ public: int s;//源城市 int d;//目的城市 int weight;//路程长 权值 int charge;//收费 vertexNode()=default; vertexNode(int s_,int d_,int w_,int c_):s{s_},d{d_},weight{w_},charge{c_}{}; }; class AdjacencyLinkGraphic{ public: vector<vector<vertexNode*>> vertexs;//二维数组, 存的值是结点 包含该点的路径和收费 vertexs[i][j] i是起点 j是终点 int cityNum{0}; int highwayNum{0}; int s;//出发城市 int d;//目的城市 AdjacencyLinkGraphic()=default; AdjacencyLinkGraphic(int n_,int m_,int s_,int d_):cityNum{n_},highwayNum{m_},s{s_},d{d_}{}; void build(){ vertexs=vector<vector<vertexNode*>>(cityNum,vector<vertexNode*>(cityNum,nullptr)); int s,d,w,c; for(int i=0;i<highwayNum;i++){ scanf("%d %d %d %d",&s,&d,&w,&c); vertexs[s][d]=new vertexNode{s,d,w,c}; vertexs[d][s]=new vertexNode{d,s,w,c}; } } void dijkstra(){ vector<int> visited(cityNum); visited[s]=1; int u;//起点 的 未访问的 最小权值的 邻接点 // 先将s的访问位置为1, // 1.找到u 然后将u的访问位置为1 // 2.先由起点的最小权值邻接点 u 开始, 寻找起点s 经由 u 到u的邻接点 j 的总权值是否小于 s到j的权值 // 3.如果经由 s 经由 u 到 j 的的路径权值小于s到j的权值 ,就更新s到j的权值为 (s到u的权值)+(u到j的权值) // 循环直到s的邻接点全部遍历完毕,这时就得到了s到任意连通点的最小路径长 和 对应的收费 //直接输出 vertexs[s][d]的路径长 和 收费 for(int i=0;i<cityNum;i++){ int min=999999; for(int j=0;j<cityNum;j++){ if( vertexs[s][j] && !visited[j] && vertexs[s][j]->weight < min){ min= vertexs[s][j]->weight; u = j; } } visited[u]=1; for(int j=0; j<cityNum; j++){ if( vertexs[u][j] && vertexs[u][j]->weight <= 99999 ){ if( vertexs[u][j] && vertexs[s][u] && vertexs[s][j] ){//确认为连通点 if(vertexs[s][j]->weight == vertexs[s][u]->weight + vertexs[u][j]->weight){ if(vertexs[s][j]->charge > vertexs[s][u]->charge + vertexs[u][j]->charge) vertexs[s][j]->charge=vertexs[s][u]->charge+vertexs[u][j]->charge; }else if(vertexs[s][j]->weight > vertexs[s][u]->weight + vertexs[u][j]->weight){ //更新由s到j的最小权值和对应的路费 vertexs[s][j]->weight = vertexs[s][u]->weight + vertexs[u][j]->weight; vertexs[s][j]->charge = vertexs[s][u]->charge + vertexs[u][j]->charge; } } } } } cout << vertexs[s][d]->weight <<" "<< vertexs[s][d]->charge<<endl; } }; int main(){ int n,m,s,d; cin >> n >> m >> s >> d ; AdjacencyLinkGraphic ALG{n,m,s,d}; ALG.build(); ALG.dijkstra(); return 0; }
原文:https://www.cnblogs.com/ichiha/p/14801790.html