最短路径问题,首先想到了贪心算法实现的dijkstra算法;这道题我用了链表的存储方式,其实用邻接矩阵也可以,主要为了练手,并且链表比矩阵要节约空间;
-
题目描述:
-
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
-
输入:
-
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
-
输出:
-
输出 一行有两个数, 最短距离及其花费。
-
样例输入:
-
3 2 1 2 5 6 2 3 4 5 1 3 0 0
-
样例输出:9 11AC代码如下(主要运用了链表+Dijkstra算法):
#include
<stdio.h>#include
<string.h>#define
inf 10000000const
int
Maxn = 200005;int
N,M;int
visit[1001];//标记某个节点是否被求出最短距离int
first[1001];//存储每个节点为始点的链表的第一个边的标号struct
Edge{ int
target;//终点 int
next;//下一条边的标号 int
dt,ct;//边的长度和花费}edge[Maxn];struct
BNode{ int
dist,cost;}Node[1001];//到达某点的最短路和花费//相当于链表的头插发,很有意思。比用邻接矩阵高效多了void
addEdge(int
index, int
u, int
v, int
d, int
c){ edge[index].next
= first[u];//将这条边插入到u为初始节点的链表的头结点处 edge[index].target
= v; edge[index].dt
= d; edge[index].ct
= c; first[u]
= index;}int
findMinNode(){//在剩下的所有节点中找最小的 int
i, Max = inf; int
index = 0; for(i
= 1; i <= N; i++){ if(Node[i].dist
< Max && !visit[i]){ Max
= Node[i].dist; index
= i; } } return
index;}void
dijk(int
s){ int
i; int
flag = 1; Node[s].cost
= Node[s].dist = 0; while(flag
< N){//更新N-1次 int
x = findMinNode(); if(!x)
break; visit[x]
= 1; flag++; for(i
= first[x]; i != -1; i = edge[i].next){ int
target = edge[i].target; if(Node[x].dist
+ edge[i].dt < Node[target].dist && !visit[target]){//更新节点 Node[target].dist
= Node[x].dist + edge[i].dt; Node[target].cost
= Node[x].cost + edge[i].ct; }else
if(Node[x].dist
+ edge[i].dt == Node[target].dist && !visit[target]){ //如果存在多条路径,更新最小花费节点 if(Node[x].cost
+ edge[i].ct < Node[target].cost){ Node[target].cost
= Node[x].cost + edge[i].ct; } } } }}int
main(){ int
u, v, d, c; int
s, t; while(scanf("%d
%d",&N,&M)
!= EOF && (N != 0 || M != 0)){ int
index = 0; memset(first,-1,sizeof(first)); for(int
i = 1; i <= N; i++){ Node[i].dist
= Node[i].cost = inf; } memset(visit,
0, sizeof(visit)); for(int
i = 0; i < M; i++){ scanf("%d
%d %d %d",&u,&v,&d,&c); addEdge(index,
u, v, d, c); index++; addEdge(index,
v, u, d, c); index++; } scanf("%d
%d",
&s, &t); dijk(s); printf("%d
%d\n",Node[t].dist,Node[t].cost); }}/************************************************************** Problem:
1008 User:
姜超 Language:
C++ Result:
Accepted Time:10
ms Memory:4160
kb****************************************************************/
本文介绍了一个基于Dijkstra算法解决最短路径问题的具体实例。通过使用链表而非邻接矩阵来节省空间,实现了从起点到终点的最短路径及花费计算。

5126

被折叠的 条评论
为什么被折叠?



