https://blog.csdn.net/KO812605128/article/details/98987167 弗洛伊德(Floyd)算法
数据结构实验之图论七:驴友计划
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
做为一个资深驴友,小新有一张珍藏的自驾游线路图,图上详细的标注了全国各个城市之间的高速公路距离和公路收费情况,现在请你编写一个程序,找出一条出发地到目的地之间的最短路径,如果有多条路径最短,则输出过路费最少的一条路径。
Input
连续T组数据输入,每组输入数据的第一行给出四个正整数N,M,s,d,其中N(2 <= N <= 500)是城市数目,城市编号从0~N-1,M是城市间高速公路的条数,s是出发地的城市编号,d是目的地的城市编号;随后M行,每行给出一条高速公路的信息,表示城市1、城市2、高速公路长度、收费额,中间以空格间隔,数字均为整数且不超过500,输入数据均保证有解。
Output
在同一行中输出路径长度和收费总额,数据间用空格间隔。
Sample Input
1
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
Sample Output
3 40
https://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html
算法实例
先给出一个无向图
用Dijkstra算法找出以A为起点的单源最短路径步骤如下
首先,v0读入,进入第一个for循环,dsi[i]就是每个点到v0的距离,即到0的距离。之后0被标记,进入下一个循环。首先看j循环里面的,如果点没有访问并且dis[j],即各个点到0的距离,找到一个最小的,min记录,now记录j = 1值,之后1被标记,之后进入下一个循环,如果j没有标记并且now(即1)到j的有通路,之后进入下一个循环里,now,即1,没有标记的点到1的距离,如果j到now(即1)的距离加上dis[now](即起点到1的距离)如果小于dis[j](即j点到0的距离)【这个点与now点的路径+起点v0到now的最短路径 < 起点v0到j的最短路径】,另一种如果当距离相同时,花费少的优选。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int n, m; ///顶点数,边数
int vis[1010]; ///点的访问情况
int money[1010][1010];///存放点与点之间的过路费
int mmap[1010][1010]; ///存放点与点之间的权值;
void dijkstra(int n, int v0, int vn)
{
int dis[1010]; ///存放v0到vn的最短路径
int mon[1010];
for(int i = 0; i < n; i++)
{
dis[i] = mmap[v0][i]; ///每个点的最短路径都设为与起点相连边上的权值,(不与起点相连的点dist[]数组的值为MAX)
mon[i] = money[v0][i]; ///每个点的过路费都初始化成与起点v0相连边上的费用。
}
vis[v0] = 1;///{
dis[v0] = 0;///---->}对起点初始化,标记该点
mon[v0] = 0;///{
for(int i = 1; i < n; i++)///除了起点一共n-1个点
{
int min = INF;///先取一个无穷大的数,可以方便以后的替换其他的值;
int now = v0; ///记录最短路径相关点的下标;
for(int j = 0; j < n; j++)///找出与起始点相连最短的路径;
{
if(!vis[j] && dis[j] < min)///如果这个点没有被访问过,而且这个点的最短路径比min小;
///(这个循环的作用是找出与起点v0相连的点所形成的边,
///那个边的权值最小(最短路径最短))
{
min = dis[j];
now = j;
}
}
vis[now] = 1;///标记这个点
for(int j = 0; j < n; j++)
{
if(!vis[j] && mmap[now][j] < INF)///如果这个点没被访问过。
///而且这个点j与点k之间存在边的话(mmap[k][j]<INF意思是k,j之间有边连接)
{
if(mmap[now][j] + dis[now] < dis[j])///这个点与k点的路径+起点v0到k的最短路径 < 起点v0到j的最短路径
{
dis[j] = mmap[now][j] + dis[now];
mon[j] = mon[j] + money[now][j];
}
else if(dis[now] + mmap[now][j] == dis[j] && mon[now] + money[now][j] < mon[j])///路径相同,钱不同 ;
mon[j] = mon[j] + mmap[now][j];
}
}
}
cout<<dis[vn]<<" "<<mon[vn]<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int v0, vn;///初始点
cin>>n>>m>>v0>>vn;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(i == j)
mmap[i][j] = 0;
else
mmap[i][j] = INF;
}
}
memset(vis, 0, sizeof(vis));
int u, v, t, s;
for(int i = 0; i < m; i++)
{
cin>>u>>v>>t>>s;
mmap[u][v] = mmap[v][u] = t;
money[u][v] = money[v][u] = s;
}
dijkstra(n, v0, vn);
}
return 0;
}
https://blog.csdn.net/weixin_39956356/article/details/80620667
这个是把路径都输出的