下学期开学大三,是到了该考虑前程的时候了。感觉自己大一大二算法基础没打好,acm也没参加,成绩也不高,唉 所以大三努力吧,接下来就是多看算法,多写博客
每天一个算法 第一个 Dijkstra算法
Dijkstra算法是一个求最短路径的算法
作用:求图中一点到图的其他所有点的最短路径,要求路径全为正的,不能有负值
时间复杂度:O(V^2)
空间复杂度:O(V)
所属算法类别:贪心算法
简单描述原理:将V(就是已经给出的图的所有点)分成两部分,S:已经求出最短路径的点的集合,T=V-S:尚未求出最短路径的点的集合,我们所要做的就是将T中的点按照距离递增的次序加到S中,并将最短距离记录到D中
具体步骤:
1.初始化S,T:任意取一个点加入到S中,这时S中只有这一个点,其余点在T中
2.初始化D:对于S中的那一个点来说,如果T中的点有到该点的弧(直接路径),则D[i]为弧值,否则则D[i]为无穷
3 从T中抽取从目前的D来看距离v0最短的一个点加入到S中
4更新D
5重复3 4直到S=V
代码实现:
#include<stdio.h>
#include<stdlib.h>
#define MAXVER 100
void Dijstra(int n,int v0);
int A[MAXVER][MAXVER];//邻接矩阵
int dist[MAXVER];//保存最短路径的距离的数组
int path[MAXVER];// path[i]为前驱顶点下标,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,
//位于"顶点i"之前的那个顶点。
bool final[MAXVER];//final[i]=true,表示已求得顶点i的最短路径
int main(){
int n;
//接收数据
printf("输入行数\n");
scanf("%d",&n);
for(int i=0;i<n;i++){
printf("第%d行\n",i);
for(int j=0;j<n;j++){
scanf("%d",&A[i][j]);
}
}
Dijstra(n,0);
for(int i=0;i<n;i++){
printf("与第%d个点的最短距离是%d\n",i,dist[i]);
}
}
void Dijstra(int n,int v0){//算法实现函数
for(int i=0;i<n;i++){//初始化dist,即步骤2
dist[i]=A[v0][i];
path[i]=v0;
final[i]=false;
}
dist[0]=0;
final[0]=0;
for(int i=0;i<n;i++){
int minds=0x7fffffff;
int ind=-1;
for(int j=0;j<n;j++){//寻找目前的路径距离中最小的一个
if(!final[j]&&dist[i]<minds){
minds=dist[j];
ind=j;
}
}
final[ind]=true;
for(int j=0;j<n;j++){//更新dist
if(!final[j]&&minds+A[ind][j]<dist[j]){
dist[j]=minds+A[ind][j];
path[j]=ind;
}
}
}
}