一、
源点:路径起始的第⼀个顶点称为源点(Source),最后⼀个顶点称为终点(Destination)。
但不要有误区,其实图中的任何⼀个顶点都可作为源点或者终点,源点与终点只是相对⼀条路径⽽⾔的。
单源最短路径:能求出源点到其他点的最短路径----->Dijkstra算法
多源最短路径:能求出每个点到其他点的最短路径--->Floyd算法
共同特点:用中转点找最短路径
二、Dijkstra算法
起点:0
dist[i]=l,0点到i点的目前的已知的最短路径的长度是l
算法流程:
1.确定第一个点x到源点的最短路径,x点一定是源点邻接点中离源点最近的
2.把x点到源点的最短路径确定下来,x去更新x的邻接点到源点的最短路径长度
3.循环:每次找到一个dist[]值最小的点y,点y的最短路径就确定下来,然后用y去更新y的邻接点到源点的最短路径长度
#include <stdio.h>
#include <stdlib.h>
#define INF 65535
//基于带权无向图 ----O(|v|^2)
int g[105][105];
int flag[105];
int dist[105];
int path[105];
int nv,ne;
int s;//起点
int end;
void dijkstra()
{
int minn;//最小的dist值
int k;//最小的dist值的点的下标
//初始化dist path
for(int i=0;i<nv;i++)
{
dist[i]=INF;
path[i]=-1;
}
//确定起点自己到自己的最短路径
flag[s]=1;
dist[s]=0;
for(int j=0;j<nv;j++)
{
if(flag[j]==0&&g[s][j]!=INF&&dist[j]>(dist[s]+g[s][j]))
{
dist[j]=dist[s]+g[s][j];
path[j]=s;
}
}
//确定其他点的最短路径
for(int i=1;i<nv;i++)
{
minn=INF;
for(int j=0;j<nv;j++)
{
if(flag[j]==0&&dist[j]<minn)
{
minn=dist[j];
k=j;
}
}
flag[k]=1;
for(int j=0;j<nv;j++)
{
if(flag[j]==0&&g[k][j]!=INF&&dist[j]>(dist[k]+g[k][j]))
{
dist[j]=dist[k]+g[k][j];
path[j]=k;
}
}
}
}
int main()
{
int x,y,w;
scanf("%d %d",&nv,&ne);
scanf("%d %d",&s,&end);
// 初始化邻接矩阵
for(int i=0;i<nv;i++)
for(int j=0;j<nv;j++)
{
if(i==j)g[i][j]=g[j][i]=0;
else g[i][j]=g[j][i]=INF;
}
//建图
for(int i=0;i<ne;i++)
{
scanf("%d %d %d",&x,&y,&w);
g[x][y]=g[y][x]=w;
}
dijkstra();
printf("起点%d 到 终点%d 的最短路径的权值和为:%d\n最短路径如下:",s,end,dist[end]);
printf("%d",end);
int p=end;
while(path[p]!=-1)
{
printf("->%d",path[p]);
p=path[p];
}
return 0;
}
/*
9 16
0 8
0 1 1
0 2 5
1 2 3
1 3 7
1 4 5
2 4 1
2 5 7
3 4 2
3 6 3
4 5 3
4 6 6
4 7 9
5 7 5
6 7 2
6 8 7
7 8 4
*/