前言
与之前不同的是,图论的问题,重实现,而不重原理,所以这几篇博客会重点记录实现部分。
实现
- 初始化:设立一个集合S(空)储存所有已确定最短距离的点,并设立距离dis数组,除了起点设为0外,其他点都设为正无穷。
- 在所有点中,找一个不在S里并且dis最小的点t
- 把t加入集合S,并且更新所有与之相连的点的距离。
- 重复执行2、3步直到每个点都加入集合S
代码
update 2024/8/3: 新打了一份代码,在老代码下面,别急着走啊( •̀ ω •́ )✧
本来打算打一份邻接表/链式前向星,但只找到了邻接矩阵的代码,反正没差多少,就写了吧。
注:赶时间,所以只能交一份陈年老代码,马蜂混乱(~ ̄▽ ̄)~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include<bits/stdc++.h> using namespace std;
int n,p,k,a,b,l; int sz[505][505]; int dis[1005],vis[1005];
int main(){ cin>>n>>p; memset(sz,-1,sizeof(sz)); for(int i=0;i<p;i++){ cin>>a>>b>>l; if(sz[a][b]!=-1)sz[a][b]=min(sz[a][b],l); else sz[a][b]=l; } for(int i=1;i<=n;i++)dis[i]=INT_MAX; dis[1]=0; while(true){ int mn=INT_MAX,mi=0; for(int i=1;i<=n;i++){ if(dis[i]<mn&&!vis[i]){ mn=dis[i]; mi=i; } } if(!mi)break; vis[mi]=1; for(int i=1;i<=n;i++){ if(sz[mi][i]!=-1&&dis[mi]+sz[mi][i]<dis[i]&&!vis[i]){ dis[i]=dis[mi]+sz[mi][i]; } } } if(dis[n]==INT_MAX){ cout<<"-1"; return 0; } cout<<dis[n]; return 0; }
|
新打了一份,照样是邻接矩阵,但是码风好看多了~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include<bits/stdc++.h> using namespace std;
const int N=505;
int n,m; int g[N][N]; int x,y,z;
int dij(int be,int en){ bool fns[N]={false}; int dis[N]; memset(dis,0x3f,sizeof(dis)); dis[be]=0; for(int i=0;i<n;i++){ int mi=-1; for(int j=1;j<=n;j++){ if(!fns[j]&&(mi==-1||dis[j]<dis[mi]))mi=j; } fns[mi]=true; if(mi==en)break; for(int j=1;j<=n;j++){ dis[j]=min(dis[j],dis[mi]+g[mi][j]); } } if(dis[en]==0x3f3f3f3f)return -1; else return dis[en]; }
int main(){ cin>>n>>m; memset(g,0x3f,sizeof(g)); while(m--){ cin>>x>>y>>z; g[x][y]=min(g[x][y],z); } cout<<dij(1,n); return 0; }
|
完结撒花o( ̄︶ ̄)o