算法
图的存储:链式前向星
1.构成:前驱数组first【】,标记数组book【】,距离数组dis【】
前驱数组 first【】:用于存储出发点n到最后第cnt条边,first【n】=cnt
标记数组book【】:标记是否该点已被使用
结构体edge【++cnt】:第 cnt 条边,存储有关边的信息
edge【cnt】.to:点,指向下一个点 v(u->v)
edge【cnt】.w:第 cnt 条边的距离
edge【cnt】.next:以u为起点上一条边的编号(第cnt条边),切记:edge【】数组对象针对“边”,故edge【】.next也存的边的信息。 edge[cnt].next=first[u];
2.利用方式:
for( i = first[ t ] ; i ! =0 ; i = edge[ i ].next )
if(!book[edge[i].to]&&dis[edge[i].to]>dis[t]+edge[i].w)
{ dis[edge[i].to]=dis[t]+edge[i].w; }① i 为边,以第 t 点为起点到达的最后一条边 i ;(t->v)
②当 i ! =0,则说明存在边时,进入for 循环;
③最后 i 为下一个点的最后一条边的编号,first【v】即为edge[ i ].next (t->v)
void add(int u,int v,int w)
{
cnt++; //边的数量
edge[cnt].to=v; //指向终点 u->v
edge[cnt].next=first[u];//以u为起点上一条边的编号,也就是与这个边起点相同的上一条边的编号
edge[cnt].w=w; //权值(距离)
first[u]=cnt; //更新以u为起点上一条边的编号
}
for(int i=first[t];i!=0;i=edge[i].next) //列举所有t连通的点
{
if(!book[edge[i].to]&&dis[edge[i].to]>dis[t]+edge[i].w)
{
dis[edge[i].to]=dis[t]+edge[i].w; //更新最短路径
}
}
刷题
1.单源最短路径
P3371 【模板】单源最短路径(弱化版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
https://www.luogu.com.cn/problem/P33711.核心思路:dijkstra单源最短路径
2.图的存储:链式前向星edge【】
3.初始化:dis【】初值赋大值
4.更新dis【】:逐一比较,更新最小值
#include <stdio.h>
#define MAX 2147483647
int first[100010];//first【a】=b;表示以a为起点的最后一条边为b
int book[100010];
int n,m,s;//n个点,m条边,s起点
int cnt=0;
struct node
{
int to;//连接的下一个点
int next;//同起点的上一条边的编号
int z;//权值
}edge[1000010];
void add(int u,int v,int w)
{
cnt++; //边的数量
edge[cnt].to=v; //指向终点 u->v
edge[cnt].next=first[u];//以u为起点上一条边的编号,也就是与这个边起点相同的上一条边的编号
edge[cnt].z=w; //权值(距离)
first[u]=cnt; //更新以u为起点上一条边的编号
}
int main()
{
int dis[20010];
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=n;i++) //初始化,dis【】存最短路径
dis[i]=MAX;
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w); //存储方式:链式前向星
}
int t=s; //s不断更新,利用变量去更替
dis[t]=0;
while(!book[t])
{
int minn=9999999;
for(int i=1;i<=n;i++)
{
if(!book[i]&&minn>dis[i])
{
minn=dis[i]; //更新最小值
t=i; //最短路径的终点v(u->v)
}
}
book[t]=1; //标记
for(int i=first[t];i!=0;i=edge[i].next)//列举所有t连通的点
{
if(!book[edge[i].to]&&dis[edge[i].to]>dis[t]+edge[i].z)
//dis[star]+edge[i].z代表最初点s到i点的最短路
{
dis[edge[i].to]=dis[t]+edge[i].z;
}
}
}
for(int i=1;i<=n;i++)
printf("%d ",dis[i]);
return 0;
}