G - 数据结构实验之图论七:驴友计划(最短路模板题Floyd算法/Dijkstra算法)
发布日期:2021-05-04 14:45:21 浏览次数:30 分类:精选文章

本文共 3494 字,大约阅读时间需要 11 分钟。

Description

做为一个资深驴友,小新有一张珍藏的自驾游线路图,图上详细的标注了全国各个城市之间的高速公路距离和公路收费情况,现在请你编写一个程序,找出一条出发地到目的地之间的最短路径,如果有多条路径最短,则输出过路费最少的一条路径。

Input

连续T组数据输入,每组输入数据的第一行给出四个正整数N,M,s,d,其中N(2 <= N <= 500)是城市数目,城市编号从0~N-1,M是城市间高速公路的条数,s是出发地的城市编号,d是目的地的城市编号;随后M行,每行给出一条高速公路的信息,表示城市1、城市2、高速公路长度、收费额,中间以空格间隔,数字均为整数且不超过500,输入数据均保证有解。

Output

在同一行中输出路径长度和收费总额,数据间用空格间隔。

Sample

Input

14 5 0 30 1 1 201 3 2 300 3 4 100 2 2 202 3 1 20

Output

3 40

答案:

Floyd算法:

#include 
#include
#define ll long long#define INF 0x3f3f3f3fconst int N = 555;using namespace std;int G[N][N]; //记录长度int P[N][N]; //记录花费//bool vis[N];void Floyd(int n,int s,int d) //Floyd算法{ for(int k = 0; k < n; k++) for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) if(G[i][j]>G[i][k]+G[k][j]) { G[i][j] = G[i][k]+G[k][j]; P[i][j] = P[i][k]+P[k][j]; } else if(G[i][j]==G[i][k]+G[k][j]) { P[i][j] = min(P[i][j],P[i][k]+P[k][j]); } printf("%d %d\n", G[s][d],P[s][d]);}void Memset(int n) //清空G数组{ int i; int j; for(i=0; i
>t; while(t--) { int n,m,s,d; cin>>n>>m>>s>>d; Memset(n); //memset(vis,0,sizeof(vis)); while(m--) { int x,y,u,v; cin>>x>>y>>u>>v; G[x][y]=G[y][x]=u; //有向图 P[x][y]=P[y][x]=v; } Floyd(n,s,d); } return 0;}

Dijkstra算法:

#include
#include
#define INF 0x3f3f3f3fint map[550][550];int vis[550];int money[550][550]; //新添加的存修路钱的数组int dist[550];int mon[550]; //接近于dist数组的用法,是一个暂时记录的作用 void Dijkstra(int n,int s, int d) //s,d分别表示起点终点{ int i, j, k, min, u; for(i = 0; i< n;i++) { dist[i] = map[s][i]; //注意s,意思是以给出的起点开始存点 mon[i] = money[s][i]; //同理,存钱 } dist[s] = 0; //以s位起点初始化 vis[s] = 1; //同上 mon[s] = 0; //同上 for(i = 1;i< n;i++) { min = INF; for(j = 0;j < n;j++) { if(min > dist[j] && !vis[j]) { //这些基本无变化 min = dist[j]; u = j; } } vis[u] = 1; for(k = 1;k <= n;k++) { if(!vis[k] && map[u][k] < INF && dist[k] > map[u][k] + dist[u]) { //这里进行改进,正常的情况存钱即可 dist[k] = map[u][k] + dist[u]; mon[k] = mon[u] + money[u][k]; } else if(!vis[k] && map[u][k] < INF && dist[k] == map[u][k] + dist[u]) { //尚若出现了长度一样,这时候判断一下往哪里修路花费少 if(mon[k] > mon[u] + money[u][k]) { mon[k] = mon[u] + money[u][k]; //存上 } } } } printf("%d %d\n",dist[d],mon[d]);//输出d,即终点所需要的长度与花费 } int main(){ int i,u,v,n,t,m,s,d,length,cost; scanf("%d",&t); while(t--) { scanf("%d %d %d %d",&n,&m,&s,&d); memset(vis,0,sizeof(vis)); memset(map,INF,sizeof(map)); for(i = 0;i< n;i++) { map[i][i] = 0; } while(m--) { scanf("%d %d %d %d",&u,&v,&length,&cost); if(map[u][v] > length) { map[u][v] = map[v][u] = length; money[u][v] = money[v][u] = cost; //存钱 } } Dijkstra(n,s,d);//点数,起点,终点 } return 0;}

最短路讲解:

最短路练习:

上一篇:H - 数据结构实验之图论八:欧拉回路(DFS+欧拉图 )
下一篇:F - 数据结构实验之图论六:村村通公路(最小生成树Prim/Kruskal)

发表评论

最新留言

关注你微信了!
[***.104.42.241]2025年04月06日 14时29分34秒