版权声明:如需转载,私聊博主 https://blog.csdn.net/lylzsx20172018/article/details/91346976
前提:经典的算法要经常看,经常复习,遇到比赛时才能得心应手
题目链接:https://cn.vjudge.net/contest/305866#problem/E
问题:求1到n的最短路径
单元最短路径:指定一个点(源点)到其余各个顶点的最短路径问题
Sample Input
5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100
Sample Output
90
第一个5是5条边,第二个5是5个点。
下面是5条边的数据
1---->2距离为20
2---->2距离为30
以此类推。。。
Dijkstra算法的步骤:
**1.**二维数组e储存顶点之间边的关系
一维数组dis储存1号顶点到其余各个顶点的初始路程
**2.**每次找到离源点(题中的1号顶点)最近的一个顶点,然后以该顶点为中心进行扩展,最终得到源点到其余所有点的最短路径
(1)所有顶点分成两部分:已知最短路径的顶点集合p和未知最短路径的顶点集合Q
book[i]=1表示i在p集合中,最初p中只有源点
(2)有源点直接到达的点dis[i]设为e[s][i],不能直接到达设为无穷大
(3)从Q中选择一个离源点最近的一个点加入p中,并进行松弛操作
(4)Q为空,算法结束
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3
int e[1002][1002],dis[1005],book[1002];
int main()
{
int T,N,mi; //T条路 N个点
scanf("%d %d",&T,&N);
memset(book,0,sizeof(book));
int a,b,c;
for(int i=1; i<=N; i++){
for(int j=1; j<=N; j++){
if(i==j)e[i][j]=0; //初始化
else
e[i][j]=inf;
}
}
for(int i=0; i<T; i++){
scanf("%d %d %d",&a,&b,&c);
if(c<e[a][b]){
e[a][b]=c; //这个地方特别注意,不同的题目有不同的要求,看清是双向还是单向,若有重复的,要最小的
e[b][a]=c;
}
}
for(int i=1; i<=N; i++)
dis[i]=e[1][i];
book[1]=1;
for(int i=1; i<=N-1; i++){
mi=inf;
int u;
for(int j=1; j<=N; j++){
if(mi>dis[j]&&book[j]==0) //找到离原点最近的点
{
mi=dis[j];
u=j;
}
}
book[u]=1;
for(int k=1; k<=N; k++){ //松弛操作
if(dis[k]>dis[u]+e[u][k])
dis[k]=dis[u]+e[u][k];
}
}
printf("%d\n",dis[N]);
return 0;
}