首页 > 编程知识 正文

单源最短路径动态规划解法,最短路径dijkstra算法例题

时间:2023-05-03 20:24:57 阅读:17681 作者:4568

旁边的表格太复杂了,弃洞前往链条前方的星星的蒟蒻,虽然链条前方的星星叫鬼畜,但是保存插图的效果真的很好。

链式正向星实际上与邻表的原理相同,只是前者用数组连接,后者用指针连接。

链式正向星结构内容:

结构l { int next; //存储与该边相同起点的边的编号int to; //当前边终点的顶点下标int w; //当前边权重(}edge[500005]; 这里的next其实是我们链表的next指针,但有点不同。

先保存图代码:

int head[10005]; void add ()//链式前向星形存储图for ) intI=0; ib; I ) { int n,m,k; cinnmk; //n,m,k表示从n到m的边的权重为k edge[i].to=m; edge[i].w=k; edge[i].next=head[n]; head[n]=i; }虽然刚开始看代码很无知,但是我们带着值进去两次就知道原理了。

输入第一边:号码当然是1: 1 2 2

此时,edge【1】. to=2,edge【1】. w=2,edge【1】. next=head【1】(由于是输入的第一条边,此时的next实际上为空) head(1) (输入以顶点1为起点的边1的编号) ) ) ) ) ) )。

第二条边号2:1 3 5

此时,edge【2】. to=2,edge【2】. w=2,edge【2】. next=head【1】(将同一起点前面的边的编号存储在当前next中,当前边与其上的同一起点的边连接起来

这样,我们把以同一个顶点为起点的边联系起来了。 (简直是隔壁钟的双胞胎兄弟。

接下来是dijkstra

原理图:

大致上,因为以a为起点,所以到a的距离为0,接下来以a为起点更新从a到其他点的距离(AB=10,AC=3),在现在的所有边中寻找最短边的终点)寻找类似a的东西,但再也没有找到过)

实现dijkstra代码:

int dis[10005]; //从源到各顶点的最短距离bool vis[10005]; //记录各顶点的访问状况的void dij () memset ) dis、lll、sizeof dis ); dis[c]=0; vis[c]=true; for(intI=head[c]; I!=-1; I=edge [ I ].next ] { dis [ edge [ I ].to ]=min (dis [ edge [ I ].to ],edge[i].w ); //以源点为起点更新边缘值for (inti=1; i=a-1; I ) { int mm=lll,post; for(intj=1; j=a; j () /查找当前最短边及其对应终点if (dis [ j ] mmvis [ j ]==false ) { mm=dis[j],post=j; } } vis[post]=true; for(intj=head[post]; j!=-1; j=edge[j].next(/使用此点作为中继点更新边值if (edge [ j ].wdis [ post ] dis[edge[j].to ] ) dis [ edge [ j ].to )

# include bits/stdc.husingnamespacestd; # defineintlonglong # define lll 9999999//为什么这里使用0x3f3f3f3f在wa上一点一点地结构l { int next; //存储与该边相同起点的边的编号int to; //当前边终点的顶点下标int w; //当前边权重(}edge[500005]; int a、b、c; int head[10005]; void add ()//链式前向星形存储图for ) intI=0; ib; I ) { int n,m,k; cinnmk; //n,m,k表示从n到m的边的权重为k edge[i].to=m; edge[i].w=k; edge[i].next=head[n]; head[n]=i; }}int dis[10005]; //从源到各顶点的最短距离bool vis[10005]; //记录各顶点访问状况的void dij () {for ) intI=1; i=10000; I ) dis[i]=lll; dis[c]=0; vis[c]=true; for(intI=head[c]; I!=-1; I=edge [ I ].next ] { dis [ edge [ I ].to ]=min (dis [ edge [ I ].to ],edge[i].w ); //以源点为起点更新边缘值for (inti=1; i=a-1; I ) { int mm=lll,post; for(intj=1; j=a; j () /查找当前最短边及其对应终点if (dis [ j ] mmvis [ j ]==false ) { mm=dis[j],post=j; } } vis[post]=true; for(intj=head[post]; j!=-1; j=edge[j].next(/使用此点作为中继点更新边值if (edge [ j ].wdis [ post ] dis[edge[j].to ] ) dis [ edge [ j ].to ) CIN.Tie(0; cout.tie(0; cinabc; for(intI=1; i=10000; I ) ) /表示所有当前顶点都没有边连接head[i]=-1。 (添加); dij (; for(intI=1; i=a; I ) if(dis[I]==lll ) cout'2147483647 ' '; else coutdis[i] '; }

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。